+
+},{}],259:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function(require) {
+
+ var state = require('../state');
+ var applier = require('../apply');
+
+ return function array(Promise) {
+
+ var applyFold = applier(Promise);
+ var toPromise = Promise.resolve;
+ var all = Promise.all;
+
+ var ar = Array.prototype.reduce;
+ var arr = Array.prototype.reduceRight;
+ var slice = Array.prototype.slice;
+
+ // Additional array combinators
+
+ Promise.any = any;
+ Promise.some = some;
+ Promise.settle = settle;
+
+ Promise.map = map;
+ Promise.filter = filter;
+ Promise.reduce = reduce;
+ Promise.reduceRight = reduceRight;
+
+ /**
+ * When this promise fulfills with an array, do
+ * onFulfilled.apply(void 0, array)
+ * @param {function} onFulfilled function to apply
+ * @returns {Promise} promise for the result of applying onFulfilled
+ */
+ Promise.prototype.spread = function(onFulfilled) {
+ return this.then(all).then(function(array) {
+ return onFulfilled.apply(this, array);
+ });
+ };
+
+ return Promise;
+
+ /**
+ * One-winner competitive race.
+ * Return a promise that will fulfill when one of the promises
+ * in the input array fulfills, or will reject when all promises
+ * have rejected.
+ * @param {array} promises
+ * @returns {Promise} promise for the first fulfilled value
+ */
+ function any(promises) {
+ var p = Promise._defer();
+ var resolver = p._handler;
+ var l = promises.length>>>0;
+
+ var pending = l;
+ var errors = [];
+
+ for (var h, x, i = 0; i < l; ++i) {
+ x = promises[i];
+ if(x === void 0 && !(i in promises)) {
+ --pending;
+ continue;
+ }
+
+ h = Promise._handler(x);
+ if(h.state() > 0) {
+ resolver.become(h);
+ Promise._visitRemaining(promises, i, h);
+ break;
+ } else {
+ h.visit(resolver, handleFulfill, handleReject);
+ }
+ }
+
+ if(pending === 0) {
+ resolver.reject(new RangeError('any(): array must not be empty'));
+ }
+
+ return p;
+
+ function handleFulfill(x) {
+ /*jshint validthis:true*/
+ errors = null;
+ this.resolve(x); // this === resolver
+ }
+
+ function handleReject(e) {
+ /*jshint validthis:true*/
+ if(this.resolved) { // this === resolver
+ return;
+ }
+
+ errors.push(e);
+ if(--pending === 0) {
+ this.reject(errors);
+ }
+ }
+ }
+
+ /**
+ * N-winner competitive race
+ * Return a promise that will fulfill when n input promises have
+ * fulfilled, or will reject when it becomes impossible for n
+ * input promises to fulfill (ie when promises.length - n + 1
+ * have rejected)
+ * @param {array} promises
+ * @param {number} n
+ * @returns {Promise} promise for the earliest n fulfillment values
+ *
+ * @deprecated
+ */
+ function some(promises, n) {
+ /*jshint maxcomplexity:7*/
+ var p = Promise._defer();
+ var resolver = p._handler;
+
+ var results = [];
+ var errors = [];
+
+ var l = promises.length>>>0;
+ var nFulfill = 0;
+ var nReject;
+ var x, i; // reused in both for() loops
+
+ // First pass: count actual array items
+ for(i=0; i<l; ++i) {
+ x = promises[i];
+ if(x === void 0 && !(i in promises)) {
+ continue;
+ }
+ ++nFulfill;
+ }
+
+ // Compute actual goals
+ n = Math.max(n, 0);
+ nReject = (nFulfill - n + 1);
+ nFulfill = Math.min(n, nFulfill);
+
+ if(n > nFulfill) {
+ resolver.reject(new RangeError('some(): array must contain at least '
+ + n + ' item(s), but had ' + nFulfill));
+ } else if(nFulfill === 0) {
+ resolver.resolve(results);
+ }
+
+ // Second pass: observe each array item, make progress toward goals
+ for(i=0; i<l; ++i) {
+ x = promises[i];
+ if(x === void 0 && !(i in promises)) {
+ continue;
+ }
+
+ Promise._handler(x).visit(resolver, fulfill, reject, resolver.notify);
+ }
+
+ return p;
+
+ function fulfill(x) {
+ /*jshint validthis:true*/
+ if(this.resolved) { // this === resolver
+ return;
+ }
+
+ results.push(x);
+ if(--nFulfill === 0) {
+ errors = null;
+ this.resolve(results);
+ }
+ }
+
+ function reject(e) {
+ /*jshint validthis:true*/
+ if(this.resolved) { // this === resolver
+ return;
+ }
+
+ errors.push(e);
+ if(--nReject === 0) {
+ results = null;
+ this.reject(errors);
+ }
+ }
+ }
+
+ /**
+ * Apply f to the value of each promise in a list of promises
+ * and return a new list containing the results.
+ * @param {array} promises
+ * @param {function(x:*, index:Number):*} f mapping function
+ * @returns {Promise}
+ */
+ function map(promises, f) {
+ return Promise._traverse(f, promises);
+ }
+
+ /**
+ * Filter the provided array of promises using the provided predicate. Input may
+ * contain promises and values
+ * @param {Array} promises array of promises and values
+ * @param {function(x:*, index:Number):boolean} predicate filtering predicate.
+ * Must return truthy (or promise for truthy) for items to retain.
+ * @returns {Promise} promise that will fulfill with an array containing all items
+ * for which predicate returned truthy.
+ */
+ function filter(promises, predicate) {
+ var a = slice.call(promises);
+ return Promise._traverse(predicate, a).then(function(keep) {
+ return filterSync(a, keep);
+ });
+ }
+
+ function filterSync(promises, keep) {
+ // Safe because we know all promises have fulfilled if we've made it this far
+ var l = keep.length;
+ var filtered = new Array(l);
+ for(var i=0, j=0; i<l; ++i) {
+ if(keep[i]) {
+ filtered[j++] = Promise._handler(promises[i]).value;
+ }
+ }
+ filtered.length = j;
+ return filtered;
+
+ }
+
+ /**
+ * Return a promise that will always fulfill with an array containing
+ * the outcome states of all input promises. The returned promise
+ * will never reject.
+ * @param {Array} promises
+ * @returns {Promise} promise for array of settled state descriptors
+ */
+ function settle(promises) {
+ return all(promises.map(settleOne));
+ }
+
+ function settleOne(p) {
+ // Optimize the case where we get an already-resolved when.js promise
+ // by extracting its state:
+ var handler;
+ if (p instanceof Promise) {
+ // This is our own Promise type and we can reach its handler internals:
+ handler = p._handler.join();
+ }
+ if((handler && handler.state() === 0) || !handler) {
+ // Either still pending, or not a Promise at all:
+ return toPromise(p).then(state.fulfilled, state.rejected);
+ }
+
+ // The promise is our own, but it is already resolved. Take a shortcut.
+ // Since we're not actually handling the resolution, we need to disable
+ // rejection reporting.
+ handler._unreport();
+ return state.inspect(handler);
+ }
+
+ /**
+ * Traditional reduce function, similar to `Array.prototype.reduce()`, but
+ * input may contain promises and/or values, and reduceFunc
+ * may return either a value or a promise, *and* initialValue may
+ * be a promise for the starting value.
+ * @param {Array|Promise} promises array or promise for an array of anything,
+ * may contain a mix of promises and values.
+ * @param {function(accumulated:*, x:*, index:Number):*} f reduce function
+ * @returns {Promise} that will resolve to the final reduced value
+ */
+ function reduce(promises, f /*, initialValue */) {
+ return arguments.length > 2 ? ar.call(promises, liftCombine(f), arguments[2])
+ : ar.call(promises, liftCombine(f));
+ }
+
+ /**
+ * Traditional reduce function, similar to `Array.prototype.reduceRight()`, but
+ * input may contain promises and/or values, and reduceFunc
+ * may return either a value or a promise, *and* initialValue may
+ * be a promise for the starting value.
+ * @param {Array|Promise} promises array or promise for an array of anything,
+ * may contain a mix of promises and values.
+ * @param {function(accumulated:*, x:*, index:Number):*} f reduce function
+ * @returns {Promise} that will resolve to the final reduced value
+ */
+ function reduceRight(promises, f /*, initialValue */) {
+ return arguments.length > 2 ? arr.call(promises, liftCombine(f), arguments[2])
+ : arr.call(promises, liftCombine(f));
+ }
+
+ function liftCombine(f) {
+ return function(z, x, i) {
+ return applyFold(f, void 0, [z,x,i]);
+ };
+ }
+ };
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
+
+},{"../apply":258,"../state":271}],260:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function() {
+
+ return function flow(Promise) {
+
+ var resolve = Promise.resolve;
+ var reject = Promise.reject;
+ var origCatch = Promise.prototype['catch'];
+
+ /**
+ * Handle the ultimate fulfillment value or rejection reason, and assume
+ * responsibility for all errors. If an error propagates out of result
+ * or handleFatalError, it will be rethrown to the host, resulting in a
+ * loud stack track on most platforms and a crash on some.
+ * @param {function?} onResult
+ * @param {function?} onError
+ * @returns {undefined}
+ */
+ Promise.prototype.done = function(onResult, onError) {
+ this._handler.visit(this._handler.receiver, onResult, onError);
+ };
+
+ /**
+ * Add Error-type and predicate matching to catch. Examples:
+ * promise.catch(TypeError, handleTypeError)
+ * .catch(predicate, handleMatchedErrors)
+ * .catch(handleRemainingErrors)
+ * @param onRejected
+ * @returns {*}
+ */
+ Promise.prototype['catch'] = Promise.prototype.otherwise = function(onRejected) {
+ if (arguments.length < 2) {
+ return origCatch.call(this, onRejected);
+ }
+
+ if(typeof onRejected !== 'function') {
+ return this.ensure(rejectInvalidPredicate);
+ }
+
+ return origCatch.call(this, createCatchFilter(arguments[1], onRejected));
+ };
+
+ /**
+ * Wraps the provided catch handler, so that it will only be called
+ * if the predicate evaluates truthy
+ * @param {?function} handler
+ * @param {function} predicate
+ * @returns {function} conditional catch handler
+ */
+ function createCatchFilter(handler, predicate) {
+ return function(e) {
+ return evaluatePredicate(e, predicate)
+ ? handler.call(this, e)
+ : reject(e);
+ };
+ }
+
+ /**
+ * Ensures that onFulfilledOrRejected will be called regardless of whether
+ * this promise is fulfilled or rejected. onFulfilledOrRejected WILL NOT
+ * receive the promises' value or reason. Any returned value will be disregarded.
+ * onFulfilledOrRejected may throw or return a rejected promise to signal
+ * an additional error.
+ * @param {function} handler handler to be called regardless of
+ * fulfillment or rejection
+ * @returns {Promise}
+ */
+ Promise.prototype['finally'] = Promise.prototype.ensure = function(handler) {
+ if(typeof handler !== 'function') {
+ return this;
+ }
+
+ return this.then(function(x) {
+ return runSideEffect(handler, this, identity, x);
+ }, function(e) {
+ return runSideEffect(handler, this, reject, e);
+ });
+ };
+
+ function runSideEffect (handler, thisArg, propagate, value) {
+ var result = handler.call(thisArg);
+ return maybeThenable(result)
+ ? propagateValue(result, propagate, value)
+ : propagate(value);
+ }
+
+ function propagateValue (result, propagate, x) {
+ return resolve(result).then(function () {
+ return propagate(x);
+ });
+ }
+
+ /**
+ * Recover from a failure by returning a defaultValue. If defaultValue
+ * is a promise, it's fulfillment value will be used. If defaultValue is
+ * a promise that rejects, the returned promise will reject with the
+ * same reason.
+ * @param {*} defaultValue
+ * @returns {Promise} new promise
+ */
+ Promise.prototype['else'] = Promise.prototype.orElse = function(defaultValue) {
+ return this.then(void 0, function() {
+ return defaultValue;
+ });
+ };
+
+ /**
+ * Shortcut for .then(function() { return value; })
+ * @param {*} value
+ * @return {Promise} a promise that:
+ * - is fulfilled if value is not a promise, or
+ * - if value is a promise, will fulfill with its value, or reject
+ * with its reason.
+ */
+ Promise.prototype['yield'] = function(value) {
+ return this.then(function() {
+ return value;
+ });
+ };
+
+ /**
+ * Runs a side effect when this promise fulfills, without changing the
+ * fulfillment value.
+ * @param {function} onFulfilledSideEffect
+ * @returns {Promise}
+ */
+ Promise.prototype.tap = function(onFulfilledSideEffect) {
+ return this.then(onFulfilledSideEffect)['yield'](this);
+ };
+
+ return Promise;
+ };
+
+ function rejectInvalidPredicate() {
+ throw new TypeError('catch predicate must be a function');
+ }
+
+ function evaluatePredicate(e, predicate) {
+ return isError(predicate) ? e instanceof predicate : predicate(e);
+ }
+
+ function isError(predicate) {
+ return predicate === Error
+ || (predicate != null && predicate.prototype instanceof Error);
+ }
+
+ function maybeThenable(x) {
+ return (typeof x === 'object' || typeof x === 'function') && x !== null;
+ }
+
+ function identity(x) {
+ return x;
+ }
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
+
+},{}],261:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+/** @author Jeff Escalante */
+
+(function(define) { 'use strict';
+define(function() {
+
+ return function fold(Promise) {
+
+ Promise.prototype.fold = function(f, z) {
+ var promise = this._beget();
+
+ this._handler.fold(function(z, x, to) {
+ Promise._handler(z).fold(function(x, z, to) {
+ to.resolve(f.call(this, z, x));
+ }, x, this, to);
+ }, z, promise._handler.receiver, promise._handler);
+
+ return promise;
+ };
+
+ return Promise;
+ };
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
+
+},{}],262:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function(require) {
+
+ var inspect = require('../state').inspect;
+
+ return function inspection(Promise) {
+
+ Promise.prototype.inspect = function() {
+ return inspect(Promise._handler(this));
+ };
+
+ return Promise;
+ };
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
+
+},{"../state":271}],263:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function() {
+
+ return function generate(Promise) {
+
+ var resolve = Promise.resolve;
+
+ Promise.iterate = iterate;
+ Promise.unfold = unfold;
+
+ return Promise;
+
+ /**
+ * @deprecated Use github.com/cujojs/most streams and most.iterate
+ * Generate a (potentially infinite) stream of promised values:
+ * x, f(x), f(f(x)), etc. until condition(x) returns true
+ * @param {function} f function to generate a new x from the previous x
+ * @param {function} condition function that, given the current x, returns
+ * truthy when the iterate should stop
+ * @param {function} handler function to handle the value produced by f
+ * @param {*|Promise} x starting value, may be a promise
+ * @return {Promise} the result of the last call to f before
+ * condition returns true
+ */
+ function iterate(f, condition, handler, x) {
+ return unfold(function(x) {
+ return [x, f(x)];
+ }, condition, handler, x);
+ }
+
+ /**
+ * @deprecated Use github.com/cujojs/most streams and most.unfold
+ * Generate a (potentially infinite) stream of promised values
+ * by applying handler(generator(seed)) iteratively until
+ * condition(seed) returns true.
+ * @param {function} unspool function that generates a [value, newSeed]
+ * given a seed.
+ * @param {function} condition function that, given the current seed, returns
+ * truthy when the unfold should stop
+ * @param {function} handler function to handle the value produced by unspool
+ * @param x {*|Promise} starting value, may be a promise
+ * @return {Promise} the result of the last value produced by unspool before
+ * condition returns true
+ */
+ function unfold(unspool, condition, handler, x) {
+ return resolve(x).then(function(seed) {
+ return resolve(condition(seed)).then(function(done) {
+ return done ? seed : resolve(unspool(seed)).spread(next);
+ });
+ });
+
+ function next(item, newSeed) {
+ return resolve(handler(item)).then(function() {
+ return unfold(unspool, condition, handler, newSeed);
+ });
+ }
+ }
+ };
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
+
+},{}],264:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function() {
+
+ return function progress(Promise) {
+
+ /**
+ * @deprecated
+ * Register a progress handler for this promise
+ * @param {function} onProgress
+ * @returns {Promise}
+ */
+ Promise.prototype.progress = function(onProgress) {
+ return this.then(void 0, void 0, onProgress);
+ };
+
+ return Promise;
+ };
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
+
+},{}],265:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function(require) {
+
+ var env = require('../env');
+ var TimeoutError = require('../TimeoutError');
+
+ function setTimeout(f, ms, x, y) {
+ return env.setTimer(function() {
+ f(x, y, ms);
+ }, ms);
+ }
+
+ return function timed(Promise) {
+ /**
+ * Return a new promise whose fulfillment value is revealed only
+ * after ms milliseconds
+ * @param {number} ms milliseconds
+ * @returns {Promise}
+ */
+ Promise.prototype.delay = function(ms) {
+ var p = this._beget();
+ this._handler.fold(handleDelay, ms, void 0, p._handler);
+ return p;
+ };
+
+ function handleDelay(ms, x, h) {
+ setTimeout(resolveDelay, ms, x, h);
+ }
+
+ function resolveDelay(x, h) {
+ h.resolve(x);
+ }
+
+ /**
+ * Return a new promise that rejects after ms milliseconds unless
+ * this promise fulfills earlier, in which case the returned promise
+ * fulfills with the same value.
+ * @param {number} ms milliseconds
+ * @param {Error|*=} reason optional rejection reason to use, defaults
+ * to a TimeoutError if not provided
+ * @returns {Promise}
+ */
+ Promise.prototype.timeout = function(ms, reason) {
+ var p = this._beget();
+ var h = p._handler;
+
+ var t = setTimeout(onTimeout, ms, reason, p._handler);
+
+ this._handler.visit(h,
+ function onFulfill(x) {
+ env.clearTimer(t);
+ this.resolve(x); // this = h
+ },
+ function onReject(x) {
+ env.clearTimer(t);
+ this.reject(x); // this = h
+ },
+ h.notify);
+
+ return p;
+ };
+
+ function onTimeout(reason, h, ms) {
+ var e = typeof reason === 'undefined'
+ ? new TimeoutError('timed out after ' + ms + 'ms')
+ : reason;
+ h.reject(e);
+ }
+
+ return Promise;
+ };
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
+
+},{"../TimeoutError":257,"../env":268}],266:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function(require) {
+
+ var setTimer = require('../env').setTimer;
+ var format = require('../format');
+
+ return function unhandledRejection(Promise) {
+
+ var logError = noop;
+ var logInfo = noop;
+ var localConsole;
+
+ if(typeof console !== 'undefined') {
+ // Alias console to prevent things like uglify's drop_console option from
+ // removing console.log/error. Unhandled rejections fall into the same
+ // category as uncaught exceptions, and build tools shouldn't silence them.
+ localConsole = console;
+ logError = typeof localConsole.error !== 'undefined'
+ ? function (e) { localConsole.error(e); }
+ : function (e) { localConsole.log(e); };
+
+ logInfo = typeof localConsole.info !== 'undefined'
+ ? function (e) { localConsole.info(e); }
+ : function (e) { localConsole.log(e); };
+ }
+
+ Promise.onPotentiallyUnhandledRejection = function(rejection) {
+ enqueue(report, rejection);
+ };
+
+ Promise.onPotentiallyUnhandledRejectionHandled = function(rejection) {
+ enqueue(unreport, rejection);
+ };
+
+ Promise.onFatalRejection = function(rejection) {
+ enqueue(throwit, rejection.value);
+ };
+
+ var tasks = [];
+ var reported = [];
+ var running = null;
+
+ function report(r) {
+ if(!r.handled) {
+ reported.push(r);
+ logError('Potentially unhandled rejection [' + r.id + '] ' + format.formatError(r.value));
+ }
+ }
+
+ function unreport(r) {
+ var i = reported.indexOf(r);
+ if(i >= 0) {
+ reported.splice(i, 1);
+ logInfo('Handled previous rejection [' + r.id + '] ' + format.formatObject(r.value));
+ }
+ }
+
+ function enqueue(f, x) {
+ tasks.push(f, x);
+ if(running === null) {
+ running = setTimer(flush, 0);
+ }
+ }
+
+ function flush() {
+ running = null;
+ while(tasks.length > 0) {
+ tasks.shift()(tasks.shift());
+ }
+ }
+
+ return Promise;
+ };
+
+ function throwit(e) {
+ throw e;
+ }
+
+ function noop() {}
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
+
+},{"../env":268,"../format":269}],267:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function() {
+
+ return function addWith(Promise) {
+ /**
+ * Returns a promise whose handlers will be called with `this` set to
+ * the supplied receiver. Subsequent promises derived from the
+ * returned promise will also have their handlers called with receiver
+ * as `this`. Calling `with` with undefined or no arguments will return
+ * a promise whose handlers will again be called in the usual Promises/A+
+ * way (no `this`) thus safely undoing any previous `with` in the
+ * promise chain.
+ *
+ * WARNING: Promises returned from `with`/`withThis` are NOT Promises/A+
+ * compliant, specifically violating 2.2.5 (http://promisesaplus.com/#point-41)
+ *
+ * @param {object} receiver `this` value for all handlers attached to
+ * the returned promise.
+ * @returns {Promise}
+ */
+ Promise.prototype['with'] = Promise.prototype.withThis = function(receiver) {
+ var p = this._beget();
+ var child = p._handler;
+ child.receiver = receiver;
+ this._handler.chain(child, receiver);
+ return p;
+ };
+
+ return Promise;
+ };
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
+
+
+},{}],268:[function(require,module,exports){
+(function (process){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+/*global process,document,setTimeout,clearTimeout,MutationObserver,WebKitMutationObserver*/
+(function(define) { 'use strict';
+define(function(require) {
+ /*jshint maxcomplexity:6*/
+
+ // Sniff "best" async scheduling option
+ // Prefer process.nextTick or MutationObserver, then check for
+ // setTimeout, and finally vertx, since its the only env that doesn't
+ // have setTimeout
+
+ var MutationObs;
+ var capturedSetTimeout = typeof setTimeout !== 'undefined' && setTimeout;
+
+ // Default env
+ var setTimer = function(f, ms) { return setTimeout(f, ms); };
+ var clearTimer = function(t) { return clearTimeout(t); };
+ var asap = function (f) { return capturedSetTimeout(f, 0); };
+
+ // Detect specific env
+ if (isNode()) { // Node
+ asap = function (f) { return process.nextTick(f); };
+
+ } else if (MutationObs = hasMutationObserver()) { // Modern browser
+ asap = initMutationObserver(MutationObs);
+
+ } else if (!capturedSetTimeout) { // vert.x
+ var vertxRequire = require;
+ var vertx = vertxRequire('vertx');
+ setTimer = function (f, ms) { return vertx.setTimer(ms, f); };
+ clearTimer = vertx.cancelTimer;
+ asap = vertx.runOnLoop || vertx.runOnContext;
+ }
+
+ return {
+ setTimer: setTimer,
+ clearTimer: clearTimer,
+ asap: asap
+ };
+
+ function isNode () {
+ return typeof process !== 'undefined' &&
+ Object.prototype.toString.call(process) === '[object process]';
+ }
+
+ function hasMutationObserver () {
+ return (typeof MutationObserver !== 'undefined' && MutationObserver) ||
+ (typeof WebKitMutationObserver !== 'undefined' && WebKitMutationObserver);
+ }
+
+ function initMutationObserver(MutationObserver) {
+ var scheduled;
+ var node = document.createTextNode('');
+ var o = new MutationObserver(run);
+ o.observe(node, { characterData: true });
+
+ function run() {
+ var f = scheduled;
+ scheduled = void 0;
+ f();
+ }
+
+ var i = 0;
+ return function (f) {
+ scheduled = f;
+ node.data = (i ^= 1);
+ };
+ }
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
+
+}).call(this,require('_process'))
+
+},{"_process":6}],269:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function() {
+
+ return {
+ formatError: formatError,
+ formatObject: formatObject,
+ tryStringify: tryStringify
+ };
+
+ /**
+ * Format an error into a string. If e is an Error and has a stack property,
+ * it's returned. Otherwise, e is formatted using formatObject, with a
+ * warning added about e not being a proper Error.
+ * @param {*} e
+ * @returns {String} formatted string, suitable for output to developers
+ */
+ function formatError(e) {
+ var s = typeof e === 'object' && e !== null && (e.stack || e.message) ? e.stack || e.message : formatObject(e);
+ return e instanceof Error ? s : s + ' (WARNING: non-Error used)';
+ }
+
+ /**
+ * Format an object, detecting "plain" objects and running them through
+ * JSON.stringify if possible.
+ * @param {Object} o
+ * @returns {string}
+ */
+ function formatObject(o) {
+ var s = String(o);
+ if(s === '[object Object]' && typeof JSON !== 'undefined') {
+ s = tryStringify(o, s);
+ }
+ return s;
+ }
+
+ /**
+ * Try to return the result of JSON.stringify(x). If that fails, return
+ * defaultValue
+ * @param {*} x
+ * @param {*} defaultValue
+ * @returns {String|*} JSON.stringify(x) or defaultValue
+ */
+ function tryStringify(x, defaultValue) {
+ try {
+ return JSON.stringify(x);
+ } catch(e) {
+ return defaultValue;
+ }
+ }
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
+
+},{}],270:[function(require,module,exports){
+(function (process){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function() {
+
+ return function makePromise(environment) {
+
+ var tasks = environment.scheduler;
+ var emitRejection = initEmitRejection();
+
+ var objectCreate = Object.create ||
+ function(proto) {
+ function Child() {}
+ Child.prototype = proto;
+ return new Child();
+ };
+
+ /**
+ * Create a promise whose fate is determined by resolver
+ * @constructor
+ * @returns {Promise} promise
+ * @name Promise
+ */
+ function Promise(resolver, handler) {
+ this._handler = resolver === Handler ? handler : init(resolver);
+ }
+
+ /**
+ * Run the supplied resolver
+ * @param resolver
+ * @returns {Pending}
+ */
+ function init(resolver) {
+ var handler = new Pending();
+
+ try {
+ resolver(promiseResolve, promiseReject, promiseNotify);
+ } catch (e) {
+ promiseReject(e);
+ }
+
+ return handler;
+
+ /**
+ * Transition from pre-resolution state to post-resolution state, notifying
+ * all listeners of the ultimate fulfillment or rejection
+ * @param {*} x resolution value
+ */
+ function promiseResolve (x) {
+ handler.resolve(x);
+ }
+ /**
+ * Reject this promise with reason, which will be used verbatim
+ * @param {Error|*} reason rejection reason, strongly suggested
+ * to be an Error type
+ */
+ function promiseReject (reason) {
+ handler.reject(reason);
+ }
+
+ /**
+ * @deprecated
+ * Issue a progress event, notifying all progress listeners
+ * @param {*} x progress event payload to pass to all listeners
+ */
+ function promiseNotify (x) {
+ handler.notify(x);
+ }
+ }
+
+ // Creation
+
+ Promise.resolve = resolve;
+ Promise.reject = reject;
+ Promise.never = never;
+
+ Promise._defer = defer;
+ Promise._handler = getHandler;
+
+ /**
+ * Returns a trusted promise. If x is already a trusted promise, it is
+ * returned, otherwise returns a new trusted Promise which follows x.
+ * @param {*} x
+ * @return {Promise} promise
+ */
+ function resolve(x) {
+ return isPromise(x) ? x
+ : new Promise(Handler, new Async(getHandler(x)));
+ }
+
+ /**
+ * Return a reject promise with x as its reason (x is used verbatim)
+ * @param {*} x
+ * @returns {Promise} rejected promise
+ */
+ function reject(x) {
+ return new Promise(Handler, new Async(new Rejected(x)));
+ }
+
+ /**
+ * Return a promise that remains pending forever
+ * @returns {Promise} forever-pending promise.
+ */
+ function never() {
+ return foreverPendingPromise; // Should be frozen
+ }
+
+ /**
+ * Creates an internal {promise, resolver} pair
+ * @private
+ * @returns {Promise}
+ */
+ function defer() {
+ return new Promise(Handler, new Pending());
+ }
+
+ // Transformation and flow control
+
+ /**
+ * Transform this promise's fulfillment value, returning a new Promise
+ * for the transformed result. If the promise cannot be fulfilled, onRejected
+ * is called with the reason. onProgress *may* be called with updates toward
+ * this promise's fulfillment.
+ * @param {function=} onFulfilled fulfillment handler
+ * @param {function=} onRejected rejection handler
+ * @param {function=} onProgress @deprecated progress handler
+ * @return {Promise} new promise
+ */
+ Promise.prototype.then = function(onFulfilled, onRejected, onProgress) {
+ var parent = this._handler;
+ var state = parent.join().state();
+
+ if ((typeof onFulfilled !== 'function' && state > 0) ||
+ (typeof onRejected !== 'function' && state < 0)) {
+ // Short circuit: value will not change, simply share handler
+ return new this.constructor(Handler, parent);
+ }
+
+ var p = this._beget();
+ var child = p._handler;
+
+ parent.chain(child, parent.receiver, onFulfilled, onRejected, onProgress);
+
+ return p;
+ };
+
+ /**
+ * If this promise cannot be fulfilled due to an error, call onRejected to
+ * handle the error. Shortcut for .then(undefined, onRejected)
+ * @param {function?} onRejected
+ * @return {Promise}
+ */
+ Promise.prototype['catch'] = function(onRejected) {
+ return this.then(void 0, onRejected);
+ };
+
+ /**
+ * Creates a new, pending promise of the same type as this promise
+ * @private
+ * @returns {Promise}
+ */
+ Promise.prototype._beget = function() {
+ return begetFrom(this._handler, this.constructor);
+ };
+
+ function begetFrom(parent, Promise) {
+ var child = new Pending(parent.receiver, parent.join().context);
+ return new Promise(Handler, child);
+ }
+
+ // Array combinators
+
+ Promise.all = all;
+ Promise.race = race;
+ Promise._traverse = traverse;
+
+ /**
+ * Return a promise that will fulfill when all promises in the
+ * input array have fulfilled, or will reject when one of the
+ * promises rejects.
+ * @param {array} promises array of promises
+ * @returns {Promise} promise for array of fulfillment values
+ */
+ function all(promises) {
+ return traverseWith(snd, null, promises);
+ }
+
+ /**
+ * Array<Promise<X>> -> Promise<Array<f(X)>>
+ * @private
+ * @param {function} f function to apply to each promise's value
+ * @param {Array} promises array of promises
+ * @returns {Promise} promise for transformed values
+ */
+ function traverse(f, promises) {
+ return traverseWith(tryCatch2, f, promises);
+ }
+
+ function traverseWith(tryMap, f, promises) {
+ var handler = typeof f === 'function' ? mapAt : settleAt;
+
+ var resolver = new Pending();
+ var pending = promises.length >>> 0;
+ var results = new Array(pending);
+
+ for (var i = 0, x; i < promises.length && !resolver.resolved; ++i) {
+ x = promises[i];
+
+ if (x === void 0 && !(i in promises)) {
+ --pending;
+ continue;
+ }
+
+ traverseAt(promises, handler, i, x, resolver);
+ }
+
+ if(pending === 0) {
+ resolver.become(new Fulfilled(results));
+ }
+
+ return new Promise(Handler, resolver);
+
+ function mapAt(i, x, resolver) {
+ if(!resolver.resolved) {
+ traverseAt(promises, settleAt, i, tryMap(f, x, i), resolver);
+ }
+ }
+
+ function settleAt(i, x, resolver) {
+ results[i] = x;
+ if(--pending === 0) {
+ resolver.become(new Fulfilled(results));
+ }
+ }
+ }
+
+ function traverseAt(promises, handler, i, x, resolver) {
+ if (maybeThenable(x)) {
+ var h = getHandlerMaybeThenable(x);
+ var s = h.state();
+
+ if (s === 0) {
+ h.fold(handler, i, void 0, resolver);
+ } else if (s > 0) {
+ handler(i, h.value, resolver);
+ } else {
+ resolver.become(h);
+ visitRemaining(promises, i+1, h);
+ }
+ } else {
+ handler(i, x, resolver);
+ }
+ }
+
+ Promise._visitRemaining = visitRemaining;
+ function visitRemaining(promises, start, handler) {
+ for(var i=start; i<promises.length; ++i) {
+ markAsHandled(getHandler(promises[i]), handler);
+ }
+ }
+
+ function markAsHandled(h, handler) {
+ if(h === handler) {
+ return;
+ }
+
+ var s = h.state();
+ if(s === 0) {
+ h.visit(h, void 0, h._unreport);
+ } else if(s < 0) {
+ h._unreport();
+ }
+ }
+
+ /**
+ * Fulfill-reject competitive race. Return a promise that will settle
+ * to the same state as the earliest input promise to settle.
+ *
+ * WARNING: The ES6 Promise spec requires that race()ing an empty array
+ * must return a promise that is pending forever. This implementation
+ * returns a singleton forever-pending promise, the same singleton that is
+ * returned by Promise.never(), thus can be checked with ===
+ *
+ * @param {array} promises array of promises to race
+ * @returns {Promise} if input is non-empty, a promise that will settle
+ * to the same outcome as the earliest input promise to settle. if empty
+ * is empty, returns a promise that will never settle.
+ */
+ function race(promises) {
+ if(typeof promises !== 'object' || promises === null) {
+ return reject(new TypeError('non-iterable passed to race()'));
+ }
+
+ // Sigh, race([]) is untestable unless we return *something*
+ // that is recognizable without calling .then() on it.
+ return promises.length === 0 ? never()
+ : promises.length === 1 ? resolve(promises[0])
+ : runRace(promises);
+ }
+
+ function runRace(promises) {
+ var resolver = new Pending();
+ var i, x, h;
+ for(i=0; i<promises.length; ++i) {
+ x = promises[i];
+ if (x === void 0 && !(i in promises)) {
+ continue;
+ }
+
+ h = getHandler(x);
+ if(h.state() !== 0) {
+ resolver.become(h);
+ visitRemaining(promises, i+1, h);
+ break;
+ } else {
+ h.visit(resolver, resolver.resolve, resolver.reject);
+ }
+ }
+ return new Promise(Handler, resolver);
+ }
+
+ // Promise internals
+ // Below this, everything is @private
+
+ /**
+ * Get an appropriate handler for x, without checking for cycles
+ * @param {*} x
+ * @returns {object} handler
+ */
+ function getHandler(x) {
+ if(isPromise(x)) {
+ return x._handler.join();
+ }
+ return maybeThenable(x) ? getHandlerUntrusted(x) : new Fulfilled(x);
+ }
+
+ /**
+ * Get a handler for thenable x.
+ * NOTE: You must only call this if maybeThenable(x) == true
+ * @param {object|function|Promise} x
+ * @returns {object} handler
+ */
+ function getHandlerMaybeThenable(x) {
+ return isPromise(x) ? x._handler.join() : getHandlerUntrusted(x);
+ }
+
+ /**
+ * Get a handler for potentially untrusted thenable x
+ * @param {*} x
+ * @returns {object} handler
+ */
+ function getHandlerUntrusted(x) {
+ try {
+ var untrustedThen = x.then;
+ return typeof untrustedThen === 'function'
+ ? new Thenable(untrustedThen, x)
+ : new Fulfilled(x);
+ } catch(e) {
+ return new Rejected(e);
+ }
+ }
+
+ /**
+ * Handler for a promise that is pending forever
+ * @constructor
+ */
+ function Handler() {}
+
+ Handler.prototype.when
+ = Handler.prototype.become
+ = Handler.prototype.notify // deprecated
+ = Handler.prototype.fail
+ = Handler.prototype._unreport
+ = Handler.prototype._report
+ = noop;
+
+ Handler.prototype._state = 0;
+
+ Handler.prototype.state = function() {
+ return this._state;
+ };
+
+ /**
+ * Recursively collapse handler chain to find the handler
+ * nearest to the fully resolved value.
+ * @returns {object} handler nearest the fully resolved value
+ */
+ Handler.prototype.join = function() {
+ var h = this;
+ while(h.handler !== void 0) {
+ h = h.handler;
+ }
+ return h;
+ };
+
+ Handler.prototype.chain = function(to, receiver, fulfilled, rejected, progress) {
+ this.when({
+ resolver: to,
+ receiver: receiver,
+ fulfilled: fulfilled,
+ rejected: rejected,
+ progress: progress
+ });
+ };
+
+ Handler.prototype.visit = function(receiver, fulfilled, rejected, progress) {
+ this.chain(failIfRejected, receiver, fulfilled, rejected, progress);
+ };
+
+ Handler.prototype.fold = function(f, z, c, to) {
+ this.when(new Fold(f, z, c, to));
+ };
+
+ /**
+ * Handler that invokes fail() on any handler it becomes
+ * @constructor
+ */
+ function FailIfRejected() {}
+
+ inherit(Handler, FailIfRejected);
+
+ FailIfRejected.prototype.become = function(h) {
+ h.fail();
+ };
+
+ var failIfRejected = new FailIfRejected();
+
+ /**
+ * Handler that manages a queue of consumers waiting on a pending promise
+ * @constructor
+ */
+ function Pending(receiver, inheritedContext) {
+ Promise.createContext(this, inheritedContext);
+
+ this.consumers = void 0;
+ this.receiver = receiver;
+ this.handler = void 0;
+ this.resolved = false;
+ }
+
+ inherit(Handler, Pending);
+
+ Pending.prototype._state = 0;
+
+ Pending.prototype.resolve = function(x) {
+ this.become(getHandler(x));
+ };
+
+ Pending.prototype.reject = function(x) {
+ if(this.resolved) {
+ return;
+ }
+
+ this.become(new Rejected(x));
+ };
+
+ Pending.prototype.join = function() {
+ if (!this.resolved) {
+ return this;
+ }
+
+ var h = this;
+
+ while (h.handler !== void 0) {
+ h = h.handler;
+ if (h === this) {
+ return this.handler = cycle();
+ }
+ }
+
+ return h;
+ };
+
+ Pending.prototype.run = function() {
+ var q = this.consumers;
+ var handler = this.handler;
+ this.handler = this.handler.join();
+ this.consumers = void 0;
+
+ for (var i = 0; i < q.length; ++i) {
+ handler.when(q[i]);
+ }
+ };
+
+ Pending.prototype.become = function(handler) {
+ if(this.resolved) {
+ return;
+ }
+
+ this.resolved = true;
+ this.handler = handler;
+ if(this.consumers !== void 0) {
+ tasks.enqueue(this);
+ }
+
+ if(this.context !== void 0) {
+ handler._report(this.context);
+ }
+ };
+
+ Pending.prototype.when = function(continuation) {
+ if(this.resolved) {
+ tasks.enqueue(new ContinuationTask(continuation, this.handler));
+ } else {
+ if(this.consumers === void 0) {
+ this.consumers = [continuation];
+ } else {
+ this.consumers.push(continuation);
+ }
+ }
+ };
+
+ /**
+ * @deprecated
+ */
+ Pending.prototype.notify = function(x) {
+ if(!this.resolved) {
+ tasks.enqueue(new ProgressTask(x, this));
+ }
+ };
+
+ Pending.prototype.fail = function(context) {
+ var c = typeof context === 'undefined' ? this.context : context;
+ this.resolved && this.handler.join().fail(c);
+ };
+
+ Pending.prototype._report = function(context) {
+ this.resolved && this.handler.join()._report(context);
+ };
+
+ Pending.prototype._unreport = function() {
+ this.resolved && this.handler.join()._unreport();
+ };
+
+ /**
+ * Wrap another handler and force it into a future stack
+ * @param {object} handler
+ * @constructor
+ */
+ function Async(handler) {
+ this.handler = handler;
+ }
+
+ inherit(Handler, Async);
+
+ Async.prototype.when = function(continuation) {
+ tasks.enqueue(new ContinuationTask(continuation, this));
+ };
+
+ Async.prototype._report = function(context) {
+ this.join()._report(context);
+ };
+
+ Async.prototype._unreport = function() {
+ this.join()._unreport();
+ };
+
+ /**
+ * Handler that wraps an untrusted thenable and assimilates it in a future stack
+ * @param {function} then
+ * @param {{then: function}} thenable
+ * @constructor
+ */
+ function Thenable(then, thenable) {
+ Pending.call(this);
+ tasks.enqueue(new AssimilateTask(then, thenable, this));
+ }
+
+ inherit(Pending, Thenable);
+
+ /**
+ * Handler for a fulfilled promise
+ * @param {*} x fulfillment value
+ * @constructor
+ */
+ function Fulfilled(x) {
+ Promise.createContext(this);
+ this.value = x;
+ }
+
+ inherit(Handler, Fulfilled);
+
+ Fulfilled.prototype._state = 1;
+
+ Fulfilled.prototype.fold = function(f, z, c, to) {
+ runContinuation3(f, z, this, c, to);
+ };
+
+ Fulfilled.prototype.when = function(cont) {
+ runContinuation1(cont.fulfilled, this, cont.receiver, cont.resolver);
+ };
+
+ var errorId = 0;
+
+ /**
+ * Handler for a rejected promise
+ * @param {*} x rejection reason
+ * @constructor
+ */
+ function Rejected(x) {
+ Promise.createContext(this);
+
+ this.id = ++errorId;
+ this.value = x;
+ this.handled = false;
+ this.reported = false;
+
+ this._report();
+ }
+
+ inherit(Handler, Rejected);
+
+ Rejected.prototype._state = -1;
+
+ Rejected.prototype.fold = function(f, z, c, to) {
+ to.become(this);
+ };
+
+ Rejected.prototype.when = function(cont) {
+ if(typeof cont.rejected === 'function') {
+ this._unreport();
+ }
+ runContinuation1(cont.rejected, this, cont.receiver, cont.resolver);
+ };
+
+ Rejected.prototype._report = function(context) {
+ tasks.afterQueue(new ReportTask(this, context));
+ };
+
+ Rejected.prototype._unreport = function() {
+ if(this.handled) {
+ return;
+ }
+ this.handled = true;
+ tasks.afterQueue(new UnreportTask(this));
+ };
+
+ Rejected.prototype.fail = function(context) {
+ this.reported = true;
+ emitRejection('unhandledRejection', this);
+ Promise.onFatalRejection(this, context === void 0 ? this.context : context);
+ };
+
+ function ReportTask(rejection, context) {
+ this.rejection = rejection;
+ this.context = context;
+ }
+
+ ReportTask.prototype.run = function() {
+ if(!this.rejection.handled && !this.rejection.reported) {
+ this.rejection.reported = true;
+ emitRejection('unhandledRejection', this.rejection) ||
+ Promise.onPotentiallyUnhandledRejection(this.rejection, this.context);
+ }
+ };
+
+ function UnreportTask(rejection) {
+ this.rejection = rejection;
+ }
+
+ UnreportTask.prototype.run = function() {
+ if(this.rejection.reported) {
+ emitRejection('rejectionHandled', this.rejection) ||
+ Promise.onPotentiallyUnhandledRejectionHandled(this.rejection);
+ }
+ };
+
+ // Unhandled rejection hooks
+ // By default, everything is a noop
+
+ Promise.createContext
+ = Promise.enterContext
+ = Promise.exitContext
+ = Promise.onPotentiallyUnhandledRejection
+ = Promise.onPotentiallyUnhandledRejectionHandled
+ = Promise.onFatalRejection
+ = noop;
+
+ // Errors and singletons
+
+ var foreverPendingHandler = new Handler();
+ var foreverPendingPromise = new Promise(Handler, foreverPendingHandler);
+
+ function cycle() {
+ return new Rejected(new TypeError('Promise cycle'));
+ }
+
+ // Task runners
+
+ /**
+ * Run a single consumer
+ * @constructor
+ */
+ function ContinuationTask(continuation, handler) {
+ this.continuation = continuation;
+ this.handler = handler;
+ }
+
+ ContinuationTask.prototype.run = function() {
+ this.handler.join().when(this.continuation);
+ };
+
+ /**
+ * Run a queue of progress handlers
+ * @constructor
+ */
+ function ProgressTask(value, handler) {
+ this.handler = handler;
+ this.value = value;
+ }
+
+ ProgressTask.prototype.run = function() {
+ var q = this.handler.consumers;
+ if(q === void 0) {
+ return;
+ }
+
+ for (var c, i = 0; i < q.length; ++i) {
+ c = q[i];
+ runNotify(c.progress, this.value, this.handler, c.receiver, c.resolver);
+ }
+ };
+
+ /**
+ * Assimilate a thenable, sending it's value to resolver
+ * @param {function} then
+ * @param {object|function} thenable
+ * @param {object} resolver
+ * @constructor
+ */
+ function AssimilateTask(then, thenable, resolver) {
+ this._then = then;
+ this.thenable = thenable;
+ this.resolver = resolver;
+ }
+
+ AssimilateTask.prototype.run = function() {
+ var h = this.resolver;
+ tryAssimilate(this._then, this.thenable, _resolve, _reject, _notify);
+
+ function _resolve(x) { h.resolve(x); }
+ function _reject(x) { h.reject(x); }
+ function _notify(x) { h.notify(x); }
+ };
+
+ function tryAssimilate(then, thenable, resolve, reject, notify) {
+ try {
+ then.call(thenable, resolve, reject, notify);
+ } catch (e) {
+ reject(e);
+ }
+ }
+
+ /**
+ * Fold a handler value with z
+ * @constructor
+ */
+ function Fold(f, z, c, to) {
+ this.f = f; this.z = z; this.c = c; this.to = to;
+ this.resolver = failIfRejected;
+ this.receiver = this;
+ }
+
+ Fold.prototype.fulfilled = function(x) {
+ this.f.call(this.c, this.z, x, this.to);
+ };
+
+ Fold.prototype.rejected = function(x) {
+ this.to.reject(x);
+ };
+
+ Fold.prototype.progress = function(x) {
+ this.to.notify(x);
+ };
+
+ // Other helpers
+
+ /**
+ * @param {*} x
+ * @returns {boolean} true iff x is a trusted Promise
+ */
+ function isPromise(x) {
+ return x instanceof Promise;
+ }
+
+ /**
+ * Test just enough to rule out primitives, in order to take faster
+ * paths in some code
+ * @param {*} x
+ * @returns {boolean} false iff x is guaranteed *not* to be a thenable
+ */
+ function maybeThenable(x) {
+ return (typeof x === 'object' || typeof x === 'function') && x !== null;
+ }
+
+ function runContinuation1(f, h, receiver, next) {
+ if(typeof f !== 'function') {
+ return next.become(h);
+ }
+
+ Promise.enterContext(h);
+ tryCatchReject(f, h.value, receiver, next);
+ Promise.exitContext();
+ }
+
+ function runContinuation3(f, x, h, receiver, next) {
+ if(typeof f !== 'function') {
+ return next.become(h);
+ }
+
+ Promise.enterContext(h);
+ tryCatchReject3(f, x, h.value, receiver, next);
+ Promise.exitContext();
+ }
+
+ /**
+ * @deprecated
+ */
+ function runNotify(f, x, h, receiver, next) {
+ if(typeof f !== 'function') {
+ return next.notify(x);
+ }
+
+ Promise.enterContext(h);
+ tryCatchReturn(f, x, receiver, next);
+ Promise.exitContext();
+ }
+
+ function tryCatch2(f, a, b) {
+ try {
+ return f(a, b);
+ } catch(e) {
+ return reject(e);
+ }
+ }
+
+ /**
+ * Return f.call(thisArg, x), or if it throws return a rejected promise for
+ * the thrown exception
+ */
+ function tryCatchReject(f, x, thisArg, next) {
+ try {
+ next.become(getHandler(f.call(thisArg, x)));
+ } catch(e) {
+ next.become(new Rejected(e));
+ }
+ }
+
+ /**
+ * Same as above, but includes the extra argument parameter.
+ */
+ function tryCatchReject3(f, x, y, thisArg, next) {
+ try {
+ f.call(thisArg, x, y, next);
+ } catch(e) {
+ next.become(new Rejected(e));
+ }
+ }
+
+ /**
+ * @deprecated
+ * Return f.call(thisArg, x), or if it throws, *return* the exception
+ */
+ function tryCatchReturn(f, x, thisArg, next) {
+ try {
+ next.notify(f.call(thisArg, x));
+ } catch(e) {
+ next.notify(e);
+ }
+ }
+
+ function inherit(Parent, Child) {
+ Child.prototype = objectCreate(Parent.prototype);
+ Child.prototype.constructor = Child;
+ }
+
+ function snd(x, y) {
+ return y;
+ }
+
+ function noop() {}
+
+ function hasCustomEvent() {
+ if(typeof CustomEvent === 'function') {
+ try {
+ var ev = new CustomEvent('unhandledRejection');
+ return ev instanceof CustomEvent;
+ } catch (ignoredException) {}
+ }
+ return false;
+ }
+
+ function hasInternetExplorerCustomEvent() {
+ if(typeof document !== 'undefined' && typeof document.createEvent === 'function') {
+ try {
+ // Try to create one event to make sure it's supported
+ var ev = document.createEvent('CustomEvent');
+ ev.initCustomEvent('eventType', false, true, {});
+ return true;
+ } catch (ignoredException) {}
+ }
+ return false;
+ }
+
+ function initEmitRejection() {
+ /*global process, self, CustomEvent*/
+ if(typeof process !== 'undefined' && process !== null
+ && typeof process.emit === 'function') {
+ // Returning falsy here means to call the default
+ // onPotentiallyUnhandledRejection API. This is safe even in
+ // browserify since process.emit always returns falsy in browserify:
+ // https://github.com/defunctzombie/node-process/blob/master/browser.js#L40-L46
+ return function(type, rejection) {
+ return type === 'unhandledRejection'
+ ? process.emit(type, rejection.value, rejection)
+ : process.emit(type, rejection);
+ };
+ } else if(typeof self !== 'undefined' && hasCustomEvent()) {
+ return (function (self, CustomEvent) {
+ return function (type, rejection) {
+ var ev = new CustomEvent(type, {
+ detail: {
+ reason: rejection.value,
+ key: rejection
+ },
+ bubbles: false,
+ cancelable: true
+ });
+
+ return !self.dispatchEvent(ev);
+ };
+ }(self, CustomEvent));
+ } else if(typeof self !== 'undefined' && hasInternetExplorerCustomEvent()) {
+ return (function(self, document) {
+ return function(type, rejection) {
+ var ev = document.createEvent('CustomEvent');
+ ev.initCustomEvent(type, false, true, {
+ reason: rejection.value,
+ key: rejection
+ });
+
+ return !self.dispatchEvent(ev);
+ };
+ }(self, document));
+ }
+
+ return noop;
+ }
+
+ return Promise;
+ };
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
+
+}).call(this,require('_process'))
+
+},{"_process":6}],271:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+/** @author Brian Cavalier */
+/** @author John Hann */
+
+(function(define) { 'use strict';
+define(function() {
+
+ return {
+ pending: toPendingState,
+ fulfilled: toFulfilledState,
+ rejected: toRejectedState,
+ inspect: inspect
+ };
+
+ function toPendingState() {
+ return { state: 'pending' };
+ }
+
+ function toRejectedState(e) {
+ return { state: 'rejected', reason: e };
+ }
+
+ function toFulfilledState(x) {
+ return { state: 'fulfilled', value: x };
+ }
+
+ function inspect(handler) {
+ var state = handler.state();
+ return state === 0 ? toPendingState()
+ : state > 0 ? toFulfilledState(handler.value)
+ : toRejectedState(handler.value);
+ }
+
+});
+}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
+
+},{}],272:[function(require,module,exports){
+/** @license MIT License (c) copyright 2010-2014 original author or authors */
+
+/**
+ * Promises/A+ and when() implementation
+ * when is part of the cujoJS family of libraries (http://cujojs.com/)
+ * @author Brian Cavalier
+ * @author John Hann
+ */
+(function(define) { 'use strict';
+define(function (require) {
+
+ var timed = require('./lib/decorators/timed');
+ var array = require('./lib/decorators/array');
+ var flow = require('./lib/decorators/flow');
+ var fold = require('./lib/decorators/fold');
+ var inspect = require('./lib/decorators/inspect');
+ var generate = require('./lib/decorators/iterate');
+ var progress = require('./lib/decorators/progress');
+ var withThis = require('./lib/decorators/with');
+ var unhandledRejection = require('./lib/decorators/unhandledRejection');
+ var TimeoutError = require('./lib/TimeoutError');
+
+ var Promise = [array, flow, fold, generate, progress,
+ inspect, withThis, timed, unhandledRejection]
+ .reduce(function(Promise, feature) {
+ return feature(Promise);
+ }, require('./lib/Promise'));
+
+ var apply = require('./lib/apply')(Promise);
+
+ // Public API
+
+ when.promise = promise; // Create a pending promise
+ when.resolve = Promise.resolve; // Create a resolved promise
+ when.reject = Promise.reject; // Create a rejected promise
+
+ when.lift = lift; // lift a function to return promises
+ when['try'] = attempt; // call a function and return a promise
+ when.attempt = attempt; // alias for when.try
+
+ when.iterate = Promise.iterate; // DEPRECATED (use cujojs/most streams) Generate a stream of promises
+ when.unfold = Promise.unfold; // DEPRECATED (use cujojs/most streams) Generate a stream of promises
+
+ when.join = join; // Join 2 or more promises
+
+ when.all = all; // Resolve a list of promises
+ when.settle = settle; // Settle a list of promises
+
+ when.any = lift(Promise.any); // One-winner race
+ when.some = lift(Promise.some); // Multi-winner race
+ when.race = lift(Promise.race); // First-to-settle race
+
+ when.map = map; // Array.map() for promises
+ when.filter = filter; // Array.filter() for promises
+ when.reduce = lift(Promise.reduce); // Array.reduce() for promises
+ when.reduceRight = lift(Promise.reduceRight); // Array.reduceRight() for promises
+
+ when.isPromiseLike = isPromiseLike; // Is something promise-like, aka thenable
+
+ when.Promise = Promise; // Promise constructor
+ when.defer = defer; // Create a {promise, resolve, reject} tuple
+
+ // Error types
+
+ when.TimeoutError = TimeoutError;
+
+ /**
+ * Get a trusted promise for x, or by transforming x with onFulfilled
+ *
+ * @param {*} x
+ * @param {function?} onFulfilled callback to be called when x is
+ * successfully fulfilled. If promiseOrValue is an immediate value, callback
+ * will be invoked immediately.
+ * @param {function?} onRejected callback to be called when x is
+ * rejected.
+ * @param {function?} onProgress callback to be called when progress updates
+ * are issued for x. @deprecated
+ * @returns {Promise} a new promise that will fulfill with the return
+ * value of callback or errback or the completion value of promiseOrValue if
+ * callback and/or errback is not supplied.
+ */
+ function when(x, onFulfilled, onRejected, onProgress) {
+ var p = Promise.resolve(x);
+ if (arguments.length < 2) {
+ return p;
+ }
+
+ return p.then(onFulfilled, onRejected, onProgress);
+ }
+
+ /**
+ * Creates a new promise whose fate is determined by resolver.
+ * @param {function} resolver function(resolve, reject, notify)
+ * @returns {Promise} promise whose fate is determine by resolver
+ */
+ function promise(resolver) {
+ return new Promise(resolver);
+ }
+
+ /**
+ * Lift the supplied function, creating a version of f that returns
+ * promises, and accepts promises as arguments.
+ * @param {function} f
+ * @returns {Function} version of f that returns promises
+ */
+ function lift(f) {
+ return function() {
+ for(var i=0, l=arguments.length, a=new Array(l); i<l; ++i) {
+ a[i] = arguments[i];
+ }
+ return apply(f, this, a);
+ };
+ }
+
+ /**
+ * Call f in a future turn, with the supplied args, and return a promise
+ * for the result.
+ * @param {function} f
+ * @returns {Promise}
+ */
+ function attempt(f /*, args... */) {
+ /*jshint validthis:true */
+ for(var i=0, l=arguments.length-1, a=new Array(l); i<l; ++i) {
+ a[i] = arguments[i+1];
+ }
+ return apply(f, this, a);
+ }
+
+ /**
+ * Creates a {promise, resolver} pair, either or both of which
+ * may be given out safely to consumers.
+ * @return {{promise: Promise, resolve: function, reject: function, notify: function}}
+ */
+ function defer() {
+ return new Deferred();
+ }
+
+ function Deferred() {
+ var p = Promise._defer();
+
+ function resolve(x) { p._handler.resolve(x); }
+ function reject(x) { p._handler.reject(x); }
+ function notify(x) { p._handler.notify(x); }
+
+ this.promise = p;
+ this.resolve = resolve;
+ this.reject = reject;
+ this.notify = notify;
+ this.resolver = { resolve: resolve, reject: reject, notify: notify };
+ }
+
+ /**
+ * Determines if x is promise-like, i.e. a thenable object
+ * NOTE: Will return true for *any thenable object*, and isn't truly
+ * safe, since it may attempt to access the `then` property of x (i.e.
+ * clever/malicious getters may do weird things)
+ * @param {*} x anything
+ * @returns {boolean} true if x is promise-like
+ */
+ function isPromiseLike(x) {
+ return x && typeof x.then === 'function';
+ }
+
+ /**
+ * Return a promise that will resolve only once all the supplied arguments
+ * have resolved. The resolution value of the returned promise will be an array
+ * containing the resolution values of each of the arguments.
+ * @param {...*} arguments may be a mix of promises and values
+ * @returns {Promise}
+ */
+ function join(/* ...promises */) {
+ return Promise.all(arguments);
+ }
+
+ /**
+ * Return a promise that will fulfill once all input promises have
+ * fulfilled, or reject when any one input promise rejects.
+ * @param {array|Promise} promises array (or promise for an array) of promises
+ * @returns {Promise}
+ */
+ function all(promises) {
+ return when(promises, Promise.all);
+ }
+
+ /**
+ * Return a promise that will always fulfill with an array containing
+ * the outcome states of all input promises. The returned promise
+ * will only reject if `promises` itself is a rejected promise.
+ * @param {array|Promise} promises array (or promise for an array) of promises
+ * @returns {Promise} promise for array of settled state descriptors
+ */
+ function settle(promises) {
+ return when(promises, Promise.settle);
+ }
+
+ /**
+ * Promise-aware array map function, similar to `Array.prototype.map()`,
+ * but input array may contain promises or values.
+ * @param {Array|Promise} promises array of anything, may contain promises and values
+ * @param {function(x:*, index:Number):*} mapFunc map function which may
+ * return a promise or value
+ * @returns {Promise} promise that will fulfill with an array of mapped values
+ * or reject if any input promise rejects.
+ */
+ function map(promises, mapFunc) {
+ return when(promises, function(promises) {
+ return Promise.map(promises, mapFunc);
+ });
+ }
+
+ /**
+ * Filter the provided array of promises using the provided predicate. Input may
+ * contain promises and values
+ * @param {Array|Promise} promises array of promises and values
+ * @param {function(x:*, index:Number):boolean} predicate filtering predicate.
+ * Must return truthy (or promise for truthy) for items to retain.
+ * @returns {Promise} promise that will fulfill with an array containing all items
+ * for which predicate returned truthy.
+ */
+ function filter(promises, predicate) {
+ return when(promises, function(promises) {
+ return Promise.filter(promises, predicate);
+ });
+ }
+
+ return when;
+});
+})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
+
+},{"./lib/Promise":255,"./lib/TimeoutError":257,"./lib/apply":258,"./lib/decorators/array":259,"./lib/decorators/flow":260,"./lib/decorators/fold":261,"./lib/decorators/inspect":262,"./lib/decorators/iterate":263,"./lib/decorators/progress":264,"./lib/decorators/timed":265,"./lib/decorators/unhandledRejection":266,"./lib/decorators/with":267}],273:[function(require,module,exports){
+var nativeIsArray = Array.isArray
+var toString = Object.prototype.toString
+
+module.exports = nativeIsArray || isArray
+
+function isArray(obj) {
+ return toString.call(obj) === "[object Array]"
+}
+
+},{}],274:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var APIv3_1 = require("./api/APIv3");
+exports.APIv3 = APIv3_1.APIv3;
+var ModelCreator_1 = require("./api/ModelCreator");
+exports.ModelCreator = ModelCreator_1.ModelCreator;
+
+},{"./api/APIv3":287,"./api/ModelCreator":288}],275:[function(require,module,exports){
+"use strict";
+function __export(m) {
+ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("./component/Component");
+exports.Component = Component_1.Component;
+var ComponentService_1 = require("./component/ComponentService");
+exports.ComponentService = ComponentService_1.ComponentService;
+var HandlerBase_1 = require("./component/utils/HandlerBase");
+exports.HandlerBase = HandlerBase_1.HandlerBase;
+var MeshFactory_1 = require("./component/utils/MeshFactory");
+exports.MeshFactory = MeshFactory_1.MeshFactory;
+var MeshScene_1 = require("./component/utils/MeshScene");
+exports.MeshScene = MeshScene_1.MeshScene;
+var MouseOperator_1 = require("./component/utils/MouseOperator");
+exports.MouseOperator = MouseOperator_1.MouseOperator;
+var ComponentSize_1 = require("./component/utils/ComponentSize");
+exports.ComponentSize = ComponentSize_1.ComponentSize;
+var AttributionComponent_1 = require("./component/AttributionComponent");
+exports.AttributionComponent = AttributionComponent_1.AttributionComponent;
+var BackgroundComponent_1 = require("./component/BackgroundComponent");
+exports.BackgroundComponent = BackgroundComponent_1.BackgroundComponent;
+var BearingComponent_1 = require("./component/BearingComponent");
+exports.BearingComponent = BearingComponent_1.BearingComponent;
+var CacheComponent_1 = require("./component/CacheComponent");
+exports.CacheComponent = CacheComponent_1.CacheComponent;
+var CoverComponent_1 = require("./component/CoverComponent");
+exports.CoverComponent = CoverComponent_1.CoverComponent;
+var DebugComponent_1 = require("./component/DebugComponent");
+exports.DebugComponent = DebugComponent_1.DebugComponent;
+var DirectionComponent_1 = require("./component/direction/DirectionComponent");
+exports.DirectionComponent = DirectionComponent_1.DirectionComponent;
+var DirectionDOMCalculator_1 = require("./component/direction/DirectionDOMCalculator");
+exports.DirectionDOMCalculator = DirectionDOMCalculator_1.DirectionDOMCalculator;
+var DirectionDOMRenderer_1 = require("./component/direction/DirectionDOMRenderer");
+exports.DirectionDOMRenderer = DirectionDOMRenderer_1.DirectionDOMRenderer;
+var ImageComponent_1 = require("./component/ImageComponent");
+exports.ImageComponent = ImageComponent_1.ImageComponent;
+var KeyboardComponent_1 = require("./component/keyboard/KeyboardComponent");
+exports.KeyboardComponent = KeyboardComponent_1.KeyboardComponent;
+var KeyPlayHandler_1 = require("./component/keyboard/KeyPlayHandler");
+exports.KeyPlayHandler = KeyPlayHandler_1.KeyPlayHandler;
+var KeyZoomHandler_1 = require("./component/keyboard/KeyZoomHandler");
+exports.KeyZoomHandler = KeyZoomHandler_1.KeyZoomHandler;
+var KeySequenceNavigationHandler_1 = require("./component/keyboard/KeySequenceNavigationHandler");
+exports.KeySequenceNavigationHandler = KeySequenceNavigationHandler_1.KeySequenceNavigationHandler;
+var KeySpatialNavigationHandler_1 = require("./component/keyboard/KeySpatialNavigationHandler");
+exports.KeySpatialNavigationHandler = KeySpatialNavigationHandler_1.KeySpatialNavigationHandler;
+var LoadingComponent_1 = require("./component/LoadingComponent");
+exports.LoadingComponent = LoadingComponent_1.LoadingComponent;
+var Marker_1 = require("./component/marker/marker/Marker");
+exports.Marker = Marker_1.Marker;
+var MarkerComponent_1 = require("./component/marker/MarkerComponent");
+exports.MarkerComponent = MarkerComponent_1.MarkerComponent;
+var MarkerScene_1 = require("./component/marker/MarkerScene");
+exports.MarkerScene = MarkerScene_1.MarkerScene;
+var MarkerSet_1 = require("./component/marker/MarkerSet");
+exports.MarkerSet = MarkerSet_1.MarkerSet;
+var MouseComponent_1 = require("./component/mouse/MouseComponent");
+exports.MouseComponent = MouseComponent_1.MouseComponent;
+var BounceHandler_1 = require("./component/mouse/BounceHandler");
+exports.BounceHandler = BounceHandler_1.BounceHandler;
+var DragPanHandler_1 = require("./component/mouse/DragPanHandler");
+exports.DragPanHandler = DragPanHandler_1.DragPanHandler;
+var DoubleClickZoomHandler_1 = require("./component/mouse/DoubleClickZoomHandler");
+exports.DoubleClickZoomHandler = DoubleClickZoomHandler_1.DoubleClickZoomHandler;
+var EarthControlHandler_1 = require("./component/mouse/EarthControlHandler");
+exports.EarthControlHandler = EarthControlHandler_1.EarthControlHandler;
+var ScrollZoomHandler_1 = require("./component/mouse/ScrollZoomHandler");
+exports.ScrollZoomHandler = ScrollZoomHandler_1.ScrollZoomHandler;
+var TouchZoomHandler_1 = require("./component/mouse/TouchZoomHandler");
+exports.TouchZoomHandler = TouchZoomHandler_1.TouchZoomHandler;
+var ImageBoundary = require("./component/mouse/ImageBoundary");
+exports.ImageBoundary = ImageBoundary;
+var Popup_1 = require("./component/popup/popup/Popup");
+exports.Popup = Popup_1.Popup;
+var PopupComponent_1 = require("./component/popup/PopupComponent");
+exports.PopupComponent = PopupComponent_1.PopupComponent;
+var NavigationComponent_1 = require("./component/NavigationComponent");
+exports.NavigationComponent = NavigationComponent_1.NavigationComponent;
+var RouteComponent_1 = require("./component/RouteComponent");
+exports.RouteComponent = RouteComponent_1.RouteComponent;
+var SequenceComponent_1 = require("./component/sequence/SequenceComponent");
+exports.SequenceComponent = SequenceComponent_1.SequenceComponent;
+var SequenceDOMRenderer_1 = require("./component/sequence/SequenceDOMRenderer");
+exports.SequenceDOMRenderer = SequenceDOMRenderer_1.SequenceDOMRenderer;
+var SequenceMode_1 = require("./component/sequence/SequenceMode");
+exports.SequenceMode = SequenceMode_1.SequenceMode;
+var SpatialDataCache_1 = require("./component/spatialdata/SpatialDataCache");
+exports.SpatialDataCache = SpatialDataCache_1.SpatialDataCache;
+var SpatialDataComponent_1 = require("./component/spatialdata/SpatialDataComponent");
+exports.SpatialDataComponent = SpatialDataComponent_1.SpatialDataComponent;
+var SpatialDataScene_1 = require("./component/spatialdata/SpatialDataScene");
+exports.SpatialDataScene = SpatialDataScene_1.SpatialDataScene;
+var ImagePlaneComponent_1 = require("./component/imageplane/ImagePlaneComponent");
+exports.ImagePlaneComponent = ImagePlaneComponent_1.ImagePlaneComponent;
+var ImagePlaneGLRenderer_1 = require("./component/imageplane/ImagePlaneGLRenderer");
+exports.ImagePlaneGLRenderer = ImagePlaneGLRenderer_1.ImagePlaneGLRenderer;
+var Shaders_1 = require("./component/shaders/Shaders");
+exports.Shaders = Shaders_1.Shaders;
+var SimpleMarker_1 = require("./component/marker/marker/SimpleMarker");
+exports.SimpleMarker = SimpleMarker_1.SimpleMarker;
+var CircleMarker_1 = require("./component/marker/marker/CircleMarker");
+exports.CircleMarker = CircleMarker_1.CircleMarker;
+var SliderComponent_1 = require("./component/slider/SliderComponent");
+exports.SliderComponent = SliderComponent_1.SliderComponent;
+var SliderDOMRenderer_1 = require("./component/slider/SliderDOMRenderer");
+exports.SliderDOMRenderer = SliderDOMRenderer_1.SliderDOMRenderer;
+var SliderGLRenderer_1 = require("./component/slider/SliderGLRenderer");
+exports.SliderGLRenderer = SliderGLRenderer_1.SliderGLRenderer;
+var StatsComponent_1 = require("./component/StatsComponent");
+exports.StatsComponent = StatsComponent_1.StatsComponent;
+var TagHandlerBase_1 = require("./component/tag/handlers/TagHandlerBase");
+exports.TagHandlerBase = TagHandlerBase_1.TagHandlerBase;
+var CreateHandlerBase_1 = require("./component/tag/handlers/CreateHandlerBase");
+exports.CreateHandlerBase = CreateHandlerBase_1.CreateHandlerBase;
+var CreatePointHandler_1 = require("./component/tag/handlers/CreatePointHandler");
+exports.CreatePointHandler = CreatePointHandler_1.CreatePointHandler;
+var CreateVertexHandler_1 = require("./component/tag/handlers/CreateVertexHandler");
+exports.CreateVertexHandler = CreateVertexHandler_1.CreateVertexHandler;
+var CreatePolygonHandler_1 = require("./component/tag/handlers/CreatePolygonHandler");
+exports.CreatePolygonHandler = CreatePolygonHandler_1.CreatePolygonHandler;
+var CreateRectHandler_1 = require("./component/tag/handlers/CreateRectHandler");
+exports.CreateRectHandler = CreateRectHandler_1.CreateRectHandler;
+var CreateRectDragHandler_1 = require("./component/tag/handlers/CreateRectDragHandler");
+exports.CreateRectDragHandler = CreateRectDragHandler_1.CreateRectDragHandler;
+var EditVertexHandler_1 = require("./component/tag/handlers/EditVertexHandler");
+exports.EditVertexHandler = EditVertexHandler_1.EditVertexHandler;
+var Tag_1 = require("./component/tag/tag/Tag");
+exports.Tag = Tag_1.Tag;
+var OutlineTag_1 = require("./component/tag/tag/OutlineTag");
+exports.OutlineTag = OutlineTag_1.OutlineTag;
+var RenderTag_1 = require("./component/tag/tag/RenderTag");
+exports.RenderTag = RenderTag_1.RenderTag;
+var OutlineRenderTag_1 = require("./component/tag/tag/OutlineRenderTag");
+exports.OutlineRenderTag = OutlineRenderTag_1.OutlineRenderTag;
+var OutlineCreateTag_1 = require("./component/tag/tag/OutlineCreateTag");
+exports.OutlineCreateTag = OutlineCreateTag_1.OutlineCreateTag;
+var SpotTag_1 = require("./component/tag/tag/SpotTag");
+exports.SpotTag = SpotTag_1.SpotTag;
+var SpotRenderTag_1 = require("./component/tag/tag/SpotRenderTag");
+exports.SpotRenderTag = SpotRenderTag_1.SpotRenderTag;
+var TagDomain_1 = require("./component/tag/tag/TagDomain");
+exports.TagDomain = TagDomain_1.TagDomain;
+var TagComponent_1 = require("./component/tag/TagComponent");
+exports.TagComponent = TagComponent_1.TagComponent;
+var TagCreator_1 = require("./component/tag/TagCreator");
+exports.TagCreator = TagCreator_1.TagCreator;
+var TagDOMRenderer_1 = require("./component/tag/TagDOMRenderer");
+exports.TagDOMRenderer = TagDOMRenderer_1.TagDOMRenderer;
+var TagMode_1 = require("./component/tag/TagMode");
+exports.TagMode = TagMode_1.TagMode;
+var TagOperation_1 = require("./component/tag/TagOperation");
+exports.TagOperation = TagOperation_1.TagOperation;
+var TagScene_1 = require("./component/tag/TagScene");
+exports.TagScene = TagScene_1.TagScene;
+var TagSet_1 = require("./component/tag/TagSet");
+exports.TagSet = TagSet_1.TagSet;
+var Geometry_1 = require("./component/tag/geometry/Geometry");
+exports.Geometry = Geometry_1.Geometry;
+var VertexGeometry_1 = require("./component/tag/geometry/VertexGeometry");
+exports.VertexGeometry = VertexGeometry_1.VertexGeometry;
+var RectGeometry_1 = require("./component/tag/geometry/RectGeometry");
+exports.RectGeometry = RectGeometry_1.RectGeometry;
+var PointGeometry_1 = require("./component/tag/geometry/PointGeometry");
+exports.PointGeometry = PointGeometry_1.PointGeometry;
+var PolygonGeometry_1 = require("./component/tag/geometry/PolygonGeometry");
+exports.PolygonGeometry = PolygonGeometry_1.PolygonGeometry;
+var GeometryTagError_1 = require("./component/tag/error/GeometryTagError");
+exports.GeometryTagError = GeometryTagError_1.GeometryTagError;
+var ZoomComponent_1 = require("./component/zoom/ZoomComponent");
+exports.ZoomComponent = ZoomComponent_1.ZoomComponent;
+__export(require("./component/interfaces/interfaces"));
+
+},{"./component/AttributionComponent":289,"./component/BackgroundComponent":290,"./component/BearingComponent":291,"./component/CacheComponent":292,"./component/Component":293,"./component/ComponentService":294,"./component/CoverComponent":295,"./component/DebugComponent":296,"./component/ImageComponent":297,"./component/LoadingComponent":298,"./component/NavigationComponent":299,"./component/RouteComponent":300,"./component/StatsComponent":301,"./component/direction/DirectionComponent":302,"./component/direction/DirectionDOMCalculator":303,"./component/direction/DirectionDOMRenderer":304,"./component/imageplane/ImagePlaneComponent":305,"./component/imageplane/ImagePlaneGLRenderer":306,"./component/interfaces/interfaces":309,"./component/keyboard/KeyPlayHandler":310,"./component/keyboard/KeySequenceNavigationHandler":311,"./component/keyboard/KeySpatialNavigationHandler":312,"./component/keyboard/KeyZoomHandler":313,"./component/keyboard/KeyboardComponent":314,"./component/marker/MarkerComponent":316,"./component/marker/MarkerScene":317,"./component/marker/MarkerSet":318,"./component/marker/marker/CircleMarker":319,"./component/marker/marker/Marker":320,"./component/marker/marker/SimpleMarker":321,"./component/mouse/BounceHandler":322,"./component/mouse/DoubleClickZoomHandler":323,"./component/mouse/DragPanHandler":324,"./component/mouse/EarthControlHandler":325,"./component/mouse/ImageBoundary":326,"./component/mouse/MouseComponent":327,"./component/mouse/ScrollZoomHandler":328,"./component/mouse/TouchZoomHandler":329,"./component/popup/PopupComponent":331,"./component/popup/popup/Popup":332,"./component/sequence/SequenceComponent":333,"./component/sequence/SequenceDOMRenderer":334,"./component/sequence/SequenceMode":335,"./component/shaders/Shaders":336,"./component/slider/SliderComponent":337,"./component/slider/SliderDOMRenderer":338,"./component/slider/SliderGLRenderer":339,"./component/spatialdata/SpatialDataCache":340,"./component/spatialdata/SpatialDataComponent":341,"./component/spatialdata/SpatialDataScene":342,"./component/tag/TagComponent":344,"./component/tag/TagCreator":345,"./component/tag/TagDOMRenderer":346,"./component/tag/TagMode":347,"./component/tag/TagOperation":348,"./component/tag/TagScene":349,"./component/tag/TagSet":350,"./component/tag/error/GeometryTagError":351,"./component/tag/geometry/Geometry":352,"./component/tag/geometry/PointGeometry":353,"./component/tag/geometry/PolygonGeometry":354,"./component/tag/geometry/RectGeometry":355,"./component/tag/geometry/VertexGeometry":356,"./component/tag/handlers/CreateHandlerBase":357,"./component/tag/handlers/CreatePointHandler":358,"./component/tag/handlers/CreatePolygonHandler":359,"./component/tag/handlers/CreateRectDragHandler":360,"./component/tag/handlers/CreateRectHandler":361,"./component/tag/handlers/CreateVertexHandler":362,"./component/tag/handlers/EditVertexHandler":363,"./component/tag/handlers/TagHandlerBase":364,"./component/tag/tag/OutlineCreateTag":365,"./component/tag/tag/OutlineRenderTag":366,"./component/tag/tag/OutlineTag":367,"./component/tag/tag/RenderTag":368,"./component/tag/tag/SpotRenderTag":369,"./component/tag/tag/SpotTag":370,"./component/tag/tag/Tag":371,"./component/tag/tag/TagDomain":372,"./component/utils/ComponentSize":373,"./component/utils/HandlerBase":374,"./component/utils/MeshFactory":375,"./component/utils/MeshScene":376,"./component/utils/MouseOperator":377,"./component/zoom/ZoomComponent":378}],276:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var EdgeDirection_1 = require("./graph/edge/EdgeDirection");
+exports.EdgeDirection = EdgeDirection_1.EdgeDirection;
+var EdgeCalculatorSettings_1 = require("./graph/edge/EdgeCalculatorSettings");
+exports.EdgeCalculatorSettings = EdgeCalculatorSettings_1.EdgeCalculatorSettings;
+var EdgeCalculatorDirections_1 = require("./graph/edge/EdgeCalculatorDirections");
+exports.EdgeCalculatorDirections = EdgeCalculatorDirections_1.EdgeCalculatorDirections;
+var EdgeCalculatorCoefficients_1 = require("./graph/edge/EdgeCalculatorCoefficients");
+exports.EdgeCalculatorCoefficients = EdgeCalculatorCoefficients_1.EdgeCalculatorCoefficients;
+var EdgeCalculator_1 = require("./graph/edge/EdgeCalculator");
+exports.EdgeCalculator = EdgeCalculator_1.EdgeCalculator;
+
+},{"./graph/edge/EdgeCalculator":400,"./graph/edge/EdgeCalculatorCoefficients":401,"./graph/edge/EdgeCalculatorDirections":402,"./graph/edge/EdgeCalculatorSettings":403,"./graph/edge/EdgeDirection":404}],277:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var AbortMapillaryError_1 = require("./error/AbortMapillaryError");
+exports.AbortMapillaryError = AbortMapillaryError_1.AbortMapillaryError;
+var ArgumentMapillaryError_1 = require("./error/ArgumentMapillaryError");
+exports.ArgumentMapillaryError = ArgumentMapillaryError_1.ArgumentMapillaryError;
+var GraphMapillaryError_1 = require("./error/GraphMapillaryError");
+exports.GraphMapillaryError = GraphMapillaryError_1.GraphMapillaryError;
+var MapillaryError_1 = require("./error/MapillaryError");
+exports.MapillaryError = MapillaryError_1.MapillaryError;
+
+},{"./error/AbortMapillaryError":379,"./error/ArgumentMapillaryError":380,"./error/GraphMapillaryError":381,"./error/MapillaryError":382}],278:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Camera_1 = require("./geo/Camera");
+exports.Camera = Camera_1.Camera;
+var GeoCoords_1 = require("./geo/GeoCoords");
+exports.GeoCoords = GeoCoords_1.GeoCoords;
+var ViewportCoords_1 = require("./geo/ViewportCoords");
+exports.ViewportCoords = ViewportCoords_1.ViewportCoords;
+var Spatial_1 = require("./geo/Spatial");
+exports.Spatial = Spatial_1.Spatial;
+var Transform_1 = require("./geo/Transform");
+exports.Transform = Transform_1.Transform;
+var Geo = require("./geo/Geo");
+exports.Geo = Geo;
+var Lines = require("./geo/Lines");
+exports.Lines = Lines;
+
+},{"./geo/Camera":383,"./geo/Geo":384,"./geo/GeoCoords":385,"./geo/Lines":386,"./geo/Spatial":387,"./geo/Transform":388,"./geo/ViewportCoords":389}],279:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var FilterCreator_1 = require("./graph/FilterCreator");
+exports.FilterCreator = FilterCreator_1.FilterCreator;
+var Graph_1 = require("./graph/Graph");
+exports.Graph = Graph_1.Graph;
+var GraphCalculator_1 = require("./graph/GraphCalculator");
+exports.GraphCalculator = GraphCalculator_1.GraphCalculator;
+var GraphMode_1 = require("./graph/GraphMode");
+exports.GraphMode = GraphMode_1.GraphMode;
+var GraphService_1 = require("./graph/GraphService");
+exports.GraphService = GraphService_1.GraphService;
+var ImageLoadingService_1 = require("./graph/ImageLoadingService");
+exports.ImageLoadingService = ImageLoadingService_1.ImageLoadingService;
+var MeshReader_1 = require("./graph/MeshReader");
+exports.MeshReader = MeshReader_1.MeshReader;
+var Node_1 = require("./graph/Node");
+exports.Node = Node_1.Node;
+var NodeCache_1 = require("./graph/NodeCache");
+exports.NodeCache = NodeCache_1.NodeCache;
+var Sequence_1 = require("./graph/Sequence");
+exports.Sequence = Sequence_1.Sequence;
+
+},{"./graph/FilterCreator":390,"./graph/Graph":391,"./graph/GraphCalculator":392,"./graph/GraphMode":393,"./graph/GraphService":394,"./graph/ImageLoadingService":395,"./graph/MeshReader":396,"./graph/Node":397,"./graph/NodeCache":398,"./graph/Sequence":399}],280:[function(require,module,exports){
+"use strict";
+/**
+ * MapillaryJS is a WebGL JavaScript library for exploring street level imagery
+ * @name Mapillary
+ */
+function __export(m) {
+ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+__export(require("./Support"));
+var Edge_1 = require("./Edge");
+exports.EdgeDirection = Edge_1.EdgeDirection;
+var Error_1 = require("./Error");
+exports.AbortMapillaryError = Error_1.AbortMapillaryError;
+var Render_1 = require("./Render");
+exports.RenderMode = Render_1.RenderMode;
+var State_1 = require("./State");
+exports.TransitionMode = State_1.TransitionMode;
+var Viewer_1 = require("./Viewer");
+exports.Alignment = Viewer_1.Alignment;
+exports.ImageSize = Viewer_1.ImageSize;
+exports.Viewer = Viewer_1.Viewer;
+var Component_1 = require("./Component");
+exports.SliderMode = Component_1.SliderMode;
+exports.ComponentSize = Component_1.ComponentSize;
+var TagComponent = require("./component/tag/Tag");
+exports.TagComponent = TagComponent;
+var MarkerComponent = require("./component/marker/Marker");
+exports.MarkerComponent = MarkerComponent;
+var PopupComponent = require("./component/popup/Popup");
+exports.PopupComponent = PopupComponent;
+
+},{"./Component":275,"./Edge":276,"./Error":277,"./Render":281,"./State":282,"./Support":283,"./Viewer":286,"./component/marker/Marker":315,"./component/popup/Popup":330,"./component/tag/Tag":343}],281:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var DOMRenderer_1 = require("./render/DOMRenderer");
+exports.DOMRenderer = DOMRenderer_1.DOMRenderer;
+var GLRenderer_1 = require("./render/GLRenderer");
+exports.GLRenderer = GLRenderer_1.GLRenderer;
+var GLRenderStage_1 = require("./render/GLRenderStage");
+exports.GLRenderStage = GLRenderStage_1.GLRenderStage;
+var RenderCamera_1 = require("./render/RenderCamera");
+exports.RenderCamera = RenderCamera_1.RenderCamera;
+var RenderMode_1 = require("./render/RenderMode");
+exports.RenderMode = RenderMode_1.RenderMode;
+var RenderService_1 = require("./render/RenderService");
+exports.RenderService = RenderService_1.RenderService;
+
+},{"./render/DOMRenderer":405,"./render/GLRenderStage":406,"./render/GLRenderer":407,"./render/RenderCamera":408,"./render/RenderMode":409,"./render/RenderService":410}],282:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var FrameGenerator_1 = require("./state/FrameGenerator");
+exports.FrameGenerator = FrameGenerator_1.FrameGenerator;
+var RotationDelta_1 = require("./state/RotationDelta");
+exports.RotationDelta = RotationDelta_1.RotationDelta;
+var State_1 = require("./state/State");
+exports.State = State_1.State;
+var StateBase_1 = require("./state/states/StateBase");
+exports.StateBase = StateBase_1.StateBase;
+var StateContext_1 = require("./state/StateContext");
+exports.StateContext = StateContext_1.StateContext;
+var StateService_1 = require("./state/StateService");
+exports.StateService = StateService_1.StateService;
+var TransitionMode_1 = require("./state/TransitionMode");
+exports.TransitionMode = TransitionMode_1.TransitionMode;
+var EarthState_1 = require("./state/states/EarthState");
+exports.EarthState = EarthState_1.EarthState;
+var InteractiveStateBase_1 = require("./state/states/InteractiveStateBase");
+exports.InteractiveStateBase = InteractiveStateBase_1.InteractiveStateBase;
+var InteractiveWaitingState_1 = require("./state/states/InteractiveWaitingState");
+exports.InteractiveWaitingState = InteractiveWaitingState_1.InteractiveWaitingState;
+var TraversingState_1 = require("./state/states/TraversingState");
+exports.TraversingState = TraversingState_1.TraversingState;
+var WaitingState_1 = require("./state/states/WaitingState");
+exports.WaitingState = WaitingState_1.WaitingState;
+
+},{"./state/FrameGenerator":411,"./state/RotationDelta":412,"./state/State":413,"./state/StateContext":414,"./state/StateService":415,"./state/TransitionMode":416,"./state/states/EarthState":417,"./state/states/InteractiveStateBase":418,"./state/states/InteractiveWaitingState":419,"./state/states/StateBase":420,"./state/states/TraversingState":421,"./state/states/WaitingState":422}],283:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var support = require("./utils/Support");
+/**
+ * Test whether the current browser supports the full
+ * functionality of MapillaryJS.
+ *
+ * @description The full functionality includes WebGL rendering.
+ *
+ * @return {boolean}
+ *
+ * @example `var supported = Mapillary.isSupported();`
+ */
+function isSupported() {
+ return isFallbackSupported() &&
+ support.isWebGLSupportedCached();
+}
+exports.isSupported = isSupported;
+/**
+ * Test whether the current browser supports the fallback
+ * functionality of MapillaryJS.
+ *
+ * @description The fallback functionality does not include WebGL
+ * rendering, only 2D canvas rendering.
+ *
+ * @return {boolean}
+ *
+ * @example `var fallbackSupported = Mapillary.isFallbackSupported();`
+ */
+function isFallbackSupported() {
+ return support.isBrowser() &&
+ support.isBlobSupported() &&
+ support.isArraySupported() &&
+ support.isFunctionSupported() &&
+ support.isJSONSupported() &&
+ support.isObjectSupported();
+}
+exports.isFallbackSupported = isFallbackSupported;
+
+},{"./utils/Support":430}],284:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var ImageTileLoader_1 = require("./tiles/ImageTileLoader");
+exports.ImageTileLoader = ImageTileLoader_1.ImageTileLoader;
+var ImageTileStore_1 = require("./tiles/ImageTileStore");
+exports.ImageTileStore = ImageTileStore_1.ImageTileStore;
+var TextureProvider_1 = require("./tiles/TextureProvider");
+exports.TextureProvider = TextureProvider_1.TextureProvider;
+var RegionOfInterestCalculator_1 = require("./tiles/RegionOfInterestCalculator");
+exports.RegionOfInterestCalculator = RegionOfInterestCalculator_1.RegionOfInterestCalculator;
+
+},{"./tiles/ImageTileLoader":423,"./tiles/ImageTileStore":424,"./tiles/RegionOfInterestCalculator":425,"./tiles/TextureProvider":426}],285:[function(require,module,exports){
+"use strict";
+function __export(m) {
+ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+var DOM_1 = require("./utils/DOM");
+exports.DOM = DOM_1.DOM;
+var EventEmitter_1 = require("./utils/EventEmitter");
+exports.EventEmitter = EventEmitter_1.EventEmitter;
+var Settings_1 = require("./utils/Settings");
+exports.Settings = Settings_1.Settings;
+__export(require("./utils/Support"));
+var Urls_1 = require("./utils/Urls");
+exports.Urls = Urls_1.Urls;
+
+},{"./utils/DOM":427,"./utils/EventEmitter":428,"./utils/Settings":429,"./utils/Support":430,"./utils/Urls":431}],286:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Alignment_1 = require("./viewer/Alignment");
+exports.Alignment = Alignment_1.Alignment;
+var CacheService_1 = require("./viewer/CacheService");
+exports.CacheService = CacheService_1.CacheService;
+var ComponentController_1 = require("./viewer/ComponentController");
+exports.ComponentController = ComponentController_1.ComponentController;
+var Container_1 = require("./viewer/Container");
+exports.Container = Container_1.Container;
+var Observer_1 = require("./viewer/Observer");
+exports.Observer = Observer_1.Observer;
+var ImageSize_1 = require("./viewer/ImageSize");
+exports.ImageSize = ImageSize_1.ImageSize;
+var KeyboardService_1 = require("./viewer/KeyboardService");
+exports.KeyboardService = KeyboardService_1.KeyboardService;
+var LoadingService_1 = require("./viewer/LoadingService");
+exports.LoadingService = LoadingService_1.LoadingService;
+var MouseService_1 = require("./viewer/MouseService");
+exports.MouseService = MouseService_1.MouseService;
+var Navigator_1 = require("./viewer/Navigator");
+exports.Navigator = Navigator_1.Navigator;
+var PlayService_1 = require("./viewer/PlayService");
+exports.PlayService = PlayService_1.PlayService;
+var Projection_1 = require("./viewer/Projection");
+exports.Projection = Projection_1.Projection;
+var SpriteService_1 = require("./viewer/SpriteService");
+exports.SpriteService = SpriteService_1.SpriteService;
+var TouchService_1 = require("./viewer/TouchService");
+exports.TouchService = TouchService_1.TouchService;
+var Viewer_1 = require("./viewer/Viewer");
+exports.Viewer = Viewer_1.Viewer;
+
+},{"./viewer/Alignment":432,"./viewer/CacheService":433,"./viewer/ComponentController":434,"./viewer/Container":435,"./viewer/ImageSize":436,"./viewer/KeyboardService":437,"./viewer/LoadingService":438,"./viewer/MouseService":439,"./viewer/Navigator":440,"./viewer/Observer":441,"./viewer/PlayService":443,"./viewer/Projection":444,"./viewer/SpriteService":445,"./viewer/TouchService":446,"./viewer/Viewer":447}],287:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var rxjs_1 = require("rxjs");
+var API_1 = require("../API");
+/**
+ * @class APIv3
+ *
+ * @classdesc Provides methods for access of API v3.
+ */
+var APIv3 = /** @class */ (function () {
+ /**
+ * Create a new api v3 instance.
+ *
+ * @param {number} clientId - Client id for API requests.
+ * @param {number} [token] - Optional bearer token for API requests of
+ * protected resources.
+ * @param {ModelCreator} [creator] - Optional model creator instance.
+ */
+ function APIv3(clientId, token, creator) {
+ this._clientId = clientId;
+ this._modelCreator = creator != null ? creator : new API_1.ModelCreator();
+ this._model = this._modelCreator.createModel(clientId, token);
+ this._pageCount = 999;
+ this._pathImageByKey = "imageByKey";
+ this._pathImageCloseTo = "imageCloseTo";
+ this._pathImagesByH = "imagesByH";
+ this._pathImageViewAdd = "imageViewAdd";
+ this._pathSequenceByKey = "sequenceByKey";
+ this._pathSequenceViewAdd = "sequenceViewAdd";
+ this._propertiesCore = [
+ "cl",
+ "l",
+ "sequence_key",
+ ];
+ this._propertiesFill = [
+ "captured_at",
+ "captured_with_camera_uuid",
+ "user",
+ "organization_key",
+ "private",
+ "project",
+ ];
+ this._propertiesKey = [
+ "key",
+ ];
+ this._propertiesSequence = [
+ "keys",
+ ];
+ this._propertiesSpatial = [
+ "atomic_scale",
+ "c_rotation",
+ "ca",
+ "calt",
+ "camera_projection_type",
+ "cca",
+ "cfocal",
+ "ck1",
+ "ck2",
+ "gpano",
+ "height",
+ "merge_cc",
+ "merge_version",
+ "orientation",
+ "width",
+ ];
+ this._propertiesUser = [
+ "username",
+ ];
+ }
+ APIv3.prototype.imageByKeyFill$ = function (keys) {
+ return this._catchInvalidateGet$(this._wrapModelResponse$(this._model.get([
+ this._pathImageByKey,
+ keys,
+ this._propertiesKey
+ .concat(this._propertiesFill)
+ .concat(this._propertiesSpatial),
+ this._propertiesKey
+ .concat(this._propertiesUser)
+ ])).pipe(operators_1.map(function (value) {
+ if (!value) {
+ throw new Error("Images (" + keys.join(", ") + ") could not be found.");
+ }
+ return value.json.imageByKey;
+ })), this._pathImageByKey, keys);
+ };
+ APIv3.prototype.imageByKeyFull$ = function (keys) {
+ return this._catchInvalidateGet$(this._wrapModelResponse$(this._model.get([
+ this._pathImageByKey,
+ keys,
+ this._propertiesKey
+ .concat(this._propertiesCore)
+ .concat(this._propertiesFill)
+ .concat(this._propertiesSpatial),
+ this._propertiesKey
+ .concat(this._propertiesUser)
+ ])).pipe(operators_1.map(function (value) {
+ if (!value) {
+ throw new Error("Images (" + keys.join(", ") + ") could not be found.");
+ }
+ return value.json.imageByKey;
+ })), this._pathImageByKey, keys);
+ };
+ APIv3.prototype.imageCloseTo$ = function (lat, lon) {
+ var lonLat = lon + ":" + lat;
+ return this._catchInvalidateGet$(this._wrapModelResponse$(this._model.get([
+ this._pathImageCloseTo,
+ [lonLat],
+ this._propertiesKey
+ .concat(this._propertiesCore)
+ .concat(this._propertiesFill)
+ .concat(this._propertiesSpatial),
+ this._propertiesKey
+ .concat(this._propertiesUser)
+ ])).pipe(operators_1.map(function (value) {
+ return value != null ? value.json.imageCloseTo[lonLat] : null;
+ })), this._pathImageCloseTo, [lonLat]);
+ };
+ APIv3.prototype.imagesByH$ = function (hs) {
+ var _this = this;
+ return this._catchInvalidateGet$(this._wrapModelResponse$(this._model.get([
+ this._pathImagesByH,
+ hs,
+ { from: 0, to: this._pageCount },
+ this._propertiesKey
+ .concat(this._propertiesCore)
+ ])).pipe(operators_1.map(function (value) {
+ if (!value) {
+ value = { json: { imagesByH: {} } };
+ for (var _i = 0, hs_1 = hs; _i < hs_1.length; _i++) {
+ var h = hs_1[_i];
+ value.json.imagesByH[h] = {};
+ for (var i = 0; i <= _this._pageCount; i++) {
+ value.json.imagesByH[h][i] = null;
+ }
+ }
+ }
+ return value.json.imagesByH;
+ })), this._pathImagesByH, hs);
+ };
+ APIv3.prototype.imageViewAdd$ = function (keys) {
+ return this._catchInvalidateCall$(this._wrapCallModelResponse$(this._model.call([this._pathImageViewAdd], [keys])), this._pathImageViewAdd, keys);
+ };
+ APIv3.prototype.invalidateImageByKey = function (keys) {
+ this._invalidateGet(this._pathImageByKey, keys);
+ };
+ APIv3.prototype.invalidateImagesByH = function (hs) {
+ this._invalidateGet(this._pathImagesByH, hs);
+ };
+ APIv3.prototype.invalidateSequenceByKey = function (sKeys) {
+ this._invalidateGet(this._pathSequenceByKey, sKeys);
+ };
+ APIv3.prototype.setToken = function (token) {
+ this._model.invalidate([]);
+ this._model = null;
+ this._model = this._modelCreator.createModel(this._clientId, token);
+ };
+ APIv3.prototype.sequenceByKey$ = function (sequenceKeys) {
+ return this._catchInvalidateGet$(this._wrapModelResponse$(this._model.get([
+ this._pathSequenceByKey,
+ sequenceKeys,
+ this._propertiesKey
+ .concat(this._propertiesSequence)
+ ])).pipe(operators_1.map(function (value) {
+ if (!value) {
+ value = { json: { sequenceByKey: {} } };
+ }
+ for (var _i = 0, sequenceKeys_1 = sequenceKeys; _i < sequenceKeys_1.length; _i++) {
+ var sequenceKey = sequenceKeys_1[_i];
+ if (!(sequenceKey in value.json.sequenceByKey)) {
+ console.warn("Sequence data missing (" + sequenceKey + ")");
+ value.json.sequenceByKey[sequenceKey] = { key: sequenceKey, keys: [] };
+ }
+ }
+ return value.json.sequenceByKey;
+ })), this._pathSequenceByKey, sequenceKeys);
+ };
+ APIv3.prototype.sequenceViewAdd$ = function (sequenceKeys) {
+ return this._catchInvalidateCall$(this._wrapCallModelResponse$(this._model.call([this._pathSequenceViewAdd], [sequenceKeys])), this._pathSequenceViewAdd, sequenceKeys);
+ };
+ Object.defineProperty(APIv3.prototype, "clientId", {
+ get: function () {
+ return this._clientId;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ APIv3.prototype._catchInvalidateGet$ = function (observable, path, paths) {
+ var _this = this;
+ return observable.pipe(operators_1.catchError(function (error) {
+ _this._invalidateGet(path, paths);
+ throw error;
+ }));
+ };
+ APIv3.prototype._catchInvalidateCall$ = function (observable, path, paths) {
+ var _this = this;
+ return observable.pipe(operators_1.catchError(function (error) {
+ _this._invalidateCall(path, paths);
+ throw error;
+ }));
+ };
+ APIv3.prototype._invalidateGet = function (path, paths) {
+ this._model.invalidate([path, paths]);
+ };
+ APIv3.prototype._invalidateCall = function (path, paths) {
+ this._model.invalidate([path], [paths]);
+ };
+ APIv3.prototype._wrapModelResponse$ = function (modelResponse) {
+ return rxjs_1.Observable
+ .create(function (subscriber) {
+ modelResponse
+ .then(function (value) {
+ subscriber.next(value);
+ subscriber.complete();
+ }, function (error) {
+ subscriber.error(error);
+ });
+ });
+ };
+ APIv3.prototype._wrapCallModelResponse$ = function (modelResponse) {
+ return this._wrapModelResponse$(modelResponse).pipe(operators_1.map(function (value) {
+ return;
+ }));
+ };
+ return APIv3;
+}());
+exports.APIv3 = APIv3;
+exports.default = APIv3;
+
+},{"../API":274,"rxjs":27,"rxjs/operators":225}],288:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var falcor = require("falcor");
+var falcor_http_datasource_1 = require("falcor-http-datasource");
+var Utils_1 = require("../Utils");
+/**
+ * @class ModelCreator
+ *
+ * @classdesc Creates API models.
+ */
+var ModelCreator = /** @class */ (function () {
+ function ModelCreator() {
+ }
+ /**
+ * Creates a Falcor model.
+ *
+ * @description Max cache size will be set to 16 MB. Authorization
+ * header will be added if bearer token is supplied.
+ *
+ * @param {number} clientId - Client id for API requests.
+ * @param {number} [token] - Optional bearer token for API requests of
+ * protected resources.
+ * @returns {falcor.Model} Falcor model for HTTP requests.
+ */
+ ModelCreator.prototype.createModel = function (clientId, token) {
+ var configuration = {
+ crossDomain: true,
+ withCredentials: false,
+ };
+ if (token != null) {
+ configuration.headers = { "Authorization": "Bearer " + token };
+ }
+ return new falcor.Model({
+ maxSize: 16 * 1024 * 1024,
+ source: new falcor_http_datasource_1.default(Utils_1.Urls.falcorModel(clientId), configuration),
+ });
+ };
+ return ModelCreator;
+}());
+exports.ModelCreator = ModelCreator;
+exports.default = ModelCreator;
+
+},{"../Utils":285,"falcor":15,"falcor-http-datasource":10}],289:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var Component_1 = require("../Component");
+var Utils_1 = require("../Utils");
+var AttributionComponent = /** @class */ (function (_super) {
+ __extends(AttributionComponent, _super);
+ function AttributionComponent(name, container, navigator) {
+ return _super.call(this, name, container, navigator) || this;
+ }
+ AttributionComponent.prototype._activate = function () {
+ var _this = this;
+ this._disposable = rxjs_1.combineLatest(this._navigator.stateService.currentNode$, this._container.renderService.size$).pipe(operators_1.map(function (_a) {
+ var node = _a[0], size = _a[1];
+ return {
+ name: _this._name,
+ vnode: _this._getAttributionNode(node.username, node.key, node.capturedAt, size.width),
+ };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ };
+ AttributionComponent.prototype._deactivate = function () {
+ this._disposable.unsubscribe();
+ };
+ AttributionComponent.prototype._getDefaultConfiguration = function () {
+ return {};
+ };
+ AttributionComponent.prototype._getAttributionNode = function (username, key, capturedAt, width) {
+ var compact = width <= 640;
+ var mapillaryIcon = vd.h("div.AttributionMapillaryLogo", []);
+ var mapillaryLink = vd.h("a.AttributionIconContainer", { href: Utils_1.Urls.explore, target: "_blank" }, [mapillaryIcon]);
+ var imageBy = compact ? "" + username : "image by " + username;
+ var imageByContent = vd.h("div.AttributionUsername", { textContent: imageBy }, []);
+ var date = new Date(capturedAt).toDateString().split(" ");
+ var formatted = (date.length > 3 ?
+ compact ?
+ [date[3]] :
+ [date[1], date[2] + ",", date[3]] :
+ date).join(" ");
+ var dateContent = vd.h("div.AttributionDate", { textContent: formatted }, []);
+ var imageLink = vd.h("a.AttributionImageContainer", { href: Utils_1.Urls.exporeImage(key), target: "_blank" }, [imageByContent, dateContent]);
+ var compactClass = compact ? ".AttributionCompact" : "";
+ return vd.h("div.AttributionContainer" + compactClass, {}, [mapillaryLink, imageLink]);
+ };
+ AttributionComponent.componentName = "attribution";
+ return AttributionComponent;
+}(Component_1.Component));
+exports.AttributionComponent = AttributionComponent;
+Component_1.ComponentService.register(AttributionComponent);
+exports.default = AttributionComponent;
+
+},{"../Component":275,"../Utils":285,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],290:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var vd = require("virtual-dom");
+var Component_1 = require("../Component");
+var BackgroundComponent = /** @class */ (function (_super) {
+ __extends(BackgroundComponent, _super);
+ function BackgroundComponent(name, container, navigator) {
+ return _super.call(this, name, container, navigator) || this;
+ }
+ BackgroundComponent.prototype._activate = function () {
+ this._container.domRenderer.render$
+ .next({ name: this._name, vnode: this._getBackgroundNode("The viewer can't display the given image.") });
+ };
+ BackgroundComponent.prototype._deactivate = function () {
+ return;
+ };
+ BackgroundComponent.prototype._getDefaultConfiguration = function () {
+ return {};
+ };
+ BackgroundComponent.prototype._getBackgroundNode = function (notice) {
+ // todo: add condition for when to display the DOM node
+ return vd.h("div.BackgroundWrapper", {}, [
+ vd.h("p", { textContent: notice }, []),
+ ]);
+ };
+ BackgroundComponent.componentName = "background";
+ return BackgroundComponent;
+}(Component_1.Component));
+exports.BackgroundComponent = BackgroundComponent;
+Component_1.ComponentService.register(BackgroundComponent);
+exports.default = BackgroundComponent;
+
+},{"../Component":275,"virtual-dom":231}],291:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var UnitBezier = require("@mapbox/unitbezier");
+var rxjs_1 = require("rxjs");
+var Component_1 = require("../Component");
+var Geo_1 = require("../Geo");
+var ViewportCoords_1 = require("../geo/ViewportCoords");
+var ComponentSize_1 = require("./utils/ComponentSize");
+/**
+ * @class BearingComponent
+ *
+ * @classdesc Component for indicating bearing and field of view.
+ *
+ * @example
+ * ```
+ * var viewer = new Mapillary.Viewer(
+ * "<element-id>",
+ * "<client-id>",
+ * "<my key>");
+ *
+ * var bearingComponent = viewer.getComponent("bearing");
+ * bearingComponent.configure({ size: Mapillary.ComponentSize.Small });
+ * ```
+ */
+var BearingComponent = /** @class */ (function (_super) {
+ __extends(BearingComponent, _super);
+ function BearingComponent(name, container, navigator) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._spatial = new Geo_1.Spatial();
+ _this._viewportCoords = new ViewportCoords_1.default();
+ _this._svgNamespace = "http://www.w3.org/2000/svg";
+ _this._distinctThreshold = Math.PI / 360;
+ _this._animationSpeed = 0.075;
+ _this._unitBezier = new UnitBezier(0.74, 0.67, 0.38, 0.96);
+ return _this;
+ }
+ BearingComponent.prototype._activate = function () {
+ var _this = this;
+ var cameraBearingFov$ = this._container.renderService.renderCamera$.pipe(operators_1.map(function (rc) {
+ var vFov = _this._spatial.degToRad(rc.perspective.fov);
+ var hFov = rc.perspective.aspect === Number.POSITIVE_INFINITY ?
+ Math.PI :
+ Math.atan(rc.perspective.aspect * Math.tan(0.5 * vFov)) * 2;
+ return [_this._spatial.azimuthalToBearing(rc.rotation.phi), hFov];
+ }), operators_1.distinctUntilChanged(function (a1, a2) {
+ return Math.abs(a2[0] - a1[0]) < _this._distinctThreshold &&
+ Math.abs(a2[1] - a1[1]) < _this._distinctThreshold;
+ }));
+ var nodeFov$ = rxjs_1.combineLatest(this._navigator.stateService.currentState$.pipe(operators_1.distinctUntilChanged(undefined, function (frame) {
+ return frame.state.currentNode.key;
+ })), this._navigator.panService.panNodes$).pipe(operators_1.map(function (_a) {
+ var frame = _a[0], panNodes = _a[1];
+ var node = frame.state.currentNode;
+ var transform = frame.state.currentTransform;
+ if (node.pano) {
+ var panoHFov = 2 * Math.PI * node.gpano.CroppedAreaImageWidthPixels / node.gpano.FullPanoWidthPixels;
+ return [panoHFov / 2, panoHFov / 2];
+ }
+ var currentProjectedPoints = _this._computeProjectedPoints(transform);
+ var hFov = _this._spatial.degToRad(_this._computeHorizontalFov(currentProjectedPoints));
+ var hFovLeft = hFov / 2;
+ var hFovRight = hFov / 2;
+ for (var _i = 0, panNodes_1 = panNodes; _i < panNodes_1.length; _i++) {
+ var _b = panNodes_1[_i], n = _b[0], f = _b[2];
+ var diff = _this._spatial.wrap(n.ca - node.ca, -180, 180);
+ if (diff < 0) {
+ hFovLeft = _this._spatial.degToRad(Math.abs(diff)) + f / 2;
+ }
+ else {
+ hFovRight = _this._spatial.degToRad(Math.abs(diff)) + f / 2;
+ }
+ }
+ return [hFovLeft, hFovRight];
+ }), operators_1.distinctUntilChanged(function (_a, _b) {
+ var hFovLeft1 = _a[0], hFovRight1 = _a[1];
+ var hFovLeft2 = _b[0], hFovRight2 = _b[1];
+ return Math.abs(hFovLeft2 - hFovLeft1) < _this._distinctThreshold &&
+ Math.abs(hFovRight2 - hFovRight1) < _this._distinctThreshold;
+ }));
+ var offset$ = rxjs_1.combineLatest(this._navigator.stateService.currentState$.pipe(operators_1.distinctUntilChanged(undefined, function (frame) {
+ return frame.state.currentNode.key;
+ })), this._container.renderService.bearing$).pipe(operators_1.map(function (_a) {
+ var frame = _a[0], bearing = _a[1];
+ var offset = _this._spatial.degToRad(frame.state.currentNode.ca - bearing);
+ return offset;
+ }));
+ var nodeFovOperation$ = new rxjs_1.Subject();
+ var smoothNodeFov$ = nodeFovOperation$.pipe(operators_1.scan(function (state, operation) {
+ return operation(state);
+ }, { alpha: 0, curr: [0, 0, 0], prev: [0, 0, 0] }), operators_1.map(function (state) {
+ var alpha = _this._unitBezier.solve(state.alpha);
+ var curr = state.curr;
+ var prev = state.prev;
+ return [
+ _this._interpolate(prev[0], curr[0], alpha),
+ _this._interpolate(prev[1], curr[1], alpha),
+ ];
+ }));
+ this._fovSubscription = nodeFov$.pipe(operators_1.map(function (nbf) {
+ return function (state) {
+ var a = _this._unitBezier.solve(state.alpha);
+ var c = state.curr;
+ var p = state.prev;
+ var prev = [
+ _this._interpolate(p[0], c[0], a),
+ _this._interpolate(p[1], c[1], a),
+ ];
+ var curr = nbf.slice();
+ return {
+ alpha: 0,
+ curr: curr,
+ prev: prev,
+ };
+ };
+ }))
+ .subscribe(nodeFovOperation$);
+ this._fovAnimationSubscription = nodeFov$.pipe(operators_1.switchMap(function () {
+ return _this._container.renderService.renderCameraFrame$.pipe(operators_1.skip(1), operators_1.scan(function (alpha) {
+ return alpha + _this._animationSpeed;
+ }, 0), operators_1.takeWhile(function (alpha) {
+ return alpha <= 1 + _this._animationSpeed;
+ }), operators_1.map(function (alpha) {
+ return Math.min(alpha, 1);
+ }));
+ }), operators_1.map(function (alpha) {
+ return function (nbfState) {
+ return {
+ alpha: alpha,
+ curr: nbfState.curr.slice(),
+ prev: nbfState.prev.slice(),
+ };
+ };
+ }))
+ .subscribe(nodeFovOperation$);
+ var nodeBearingFov$ = rxjs_1.combineLatest(offset$, smoothNodeFov$).pipe(operators_1.map(function (_a) {
+ var offset = _a[0], fov = _a[1];
+ return [offset, fov[0], fov[1]];
+ }));
+ this._renderSubscription = rxjs_1.combineLatest(cameraBearingFov$, nodeBearingFov$, this._configuration$, this._container.renderService.size$).pipe(operators_1.map(function (_a) {
+ var _b = _a[0], cb = _b[0], cf = _b[1], _c = _a[1], no = _c[0], nfl = _c[1], nfr = _c[2], configuration = _a[2], size = _a[3];
+ var background = _this._createBackground(cb);
+ var fovIndicator = _this._createFovIndicator(nfl, nfr, no);
+ var north = _this._createNorth(cb);
+ var cameraSector = _this._createCircleSectorCompass(_this._createCircleSector(Math.max(Math.PI / 20, cf), "#FFF"));
+ var compact = configuration.size === ComponentSize_1.default.Small ||
+ configuration.size === ComponentSize_1.default.Automatic && size.width < 640 ?
+ ".BearingCompact" : "";
+ return {
+ name: _this._name,
+ vnode: vd.h("div.BearingIndicatorContainer" + compact, { oncontextmenu: function (event) { event.preventDefault(); } }, [
+ background,
+ fovIndicator,
+ north,
+ cameraSector,
+ ]),
+ };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ };
+ BearingComponent.prototype._deactivate = function () {
+ this._renderSubscription.unsubscribe();
+ this._fovSubscription.unsubscribe();
+ this._fovAnimationSubscription.unsubscribe();
+ };
+ BearingComponent.prototype._getDefaultConfiguration = function () {
+ return { size: ComponentSize_1.default.Automatic };
+ };
+ BearingComponent.prototype._createFovIndicator = function (fovLeft, fovRigth, offset) {
+ var arc = this._createFovArc(fovLeft, fovRigth);
+ var group = vd.h("g", {
+ attributes: { transform: "translate(18,18)" },
+ namespace: this._svgNamespace,
+ }, [arc]);
+ var svg = vd.h("svg", {
+ attributes: { viewBox: "0 0 36 36" },
+ namespace: this._svgNamespace,
+ style: {
+ height: "36px",
+ left: "2px",
+ position: "absolute",
+ top: "2px",
+ transform: "rotateZ(" + this._spatial.radToDeg(offset) + "deg)",
+ width: "36px",
+ },
+ }, [group]);
+ return svg;
+ };
+ BearingComponent.prototype._createFovArc = function (fovLeft, fovRigth) {
+ var radius = 16.75;
+ var strokeWidth = 2.5;
+ var fov = fovLeft + fovRigth;
+ if (fov > 2 * Math.PI - Math.PI / 90) {
+ return vd.h("circle", {
+ attributes: {
+ cx: "0",
+ cy: "0",
+ "fill-opacity": "0",
+ r: "" + radius,
+ stroke: "#FFF",
+ "stroke-width": "" + strokeWidth,
+ },
+ namespace: this._svgNamespace,
+ }, []);
+ }
+ var arcStart = -Math.PI / 2 - fovLeft;
+ var arcEnd = arcStart + fov;
+ var startX = radius * Math.cos(arcStart);
+ var startY = radius * Math.sin(arcStart);
+ var endX = radius * Math.cos(arcEnd);
+ var endY = radius * Math.sin(arcEnd);
+ var largeArc = fov >= Math.PI ? 1 : 0;
+ var description = "M " + startX + " " + startY + " A " + radius + " " + radius + " 0 " + largeArc + " 1 " + endX + " " + endY;
+ return vd.h("path", {
+ attributes: {
+ d: description,
+ "fill-opacity": "0",
+ stroke: "#FFF",
+ "stroke-width": "" + strokeWidth,
+ },
+ namespace: this._svgNamespace,
+ }, []);
+ };
+ BearingComponent.prototype._createCircleSectorCompass = function (cameraSector) {
+ var group = vd.h("g", {
+ attributes: { transform: "translate(1,1)" },
+ namespace: this._svgNamespace,
+ }, [cameraSector]);
+ var svg = vd.h("svg", {
+ attributes: { viewBox: "0 0 2 2" },
+ namespace: this._svgNamespace,
+ style: {
+ height: "26px",
+ left: "7px",
+ position: "absolute",
+ top: "7px",
+ width: "26px",
+ },
+ }, [group]);
+ return svg;
+ };
+ BearingComponent.prototype._createCircleSector = function (fov, fill) {
+ if (fov > 2 * Math.PI - Math.PI / 90) {
+ return vd.h("circle", {
+ attributes: { cx: "0", cy: "0", fill: fill, r: "1" },
+ namespace: this._svgNamespace,
+ }, []);
+ }
+ var arcStart = -Math.PI / 2 - fov / 2;
+ var arcEnd = arcStart + fov;
+ var startX = Math.cos(arcStart);
+ var startY = Math.sin(arcStart);
+ var endX = Math.cos(arcEnd);
+ var endY = Math.sin(arcEnd);
+ var largeArc = fov >= Math.PI ? 1 : 0;
+ var description = "M 0 0 " + startX + " " + startY + " A 1 1 0 " + largeArc + " 1 " + endX + " " + endY;
+ return vd.h("path", {
+ attributes: { d: description, fill: fill },
+ namespace: this._svgNamespace,
+ }, []);
+ };
+ BearingComponent.prototype._createNorth = function (bearing) {
+ var north = vd.h("div.BearingNorth", []);
+ var container = vd.h("div.BearingNorthContainer", { style: { transform: "rotateZ(" + this._spatial.radToDeg(-bearing) + "deg)" } }, [north]);
+ return container;
+ };
+ BearingComponent.prototype._createBackground = function (bearing) {
+ return vd.h("div.BearingIndicatorBackground", { style: { transform: "rotateZ(" + this._spatial.radToDeg(-bearing) + "deg)" } }, [
+ vd.h("div.BearingIndicatorBackgroundCircle", []),
+ vd.h("div.BearingIndicatorBackgroundArrowContainer", [
+ vd.h("div.BearingIndicatorBackgroundArrow", []),
+ ]),
+ ]);
+ };
+ BearingComponent.prototype._computeProjectedPoints = function (transform) {
+ var vertices = [[1, 0]];
+ var directions = [[0, 0.5]];
+ var pointsPerLine = 12;
+ return Geo_1.Geo.computeProjectedPoints(transform, vertices, directions, pointsPerLine, this._viewportCoords);
+ };
+ BearingComponent.prototype._computeHorizontalFov = function (projectedPoints) {
+ var _this = this;
+ var fovs = projectedPoints
+ .map(function (projectedPoint) {
+ return _this._coordToFov(projectedPoint[0]);
+ });
+ var fov = Math.min.apply(Math, fovs);
+ return fov;
+ };
+ BearingComponent.prototype._coordToFov = function (x) {
+ return this._spatial.radToDeg(2 * Math.atan(x));
+ };
+ BearingComponent.prototype._interpolate = function (x1, x2, alpha) {
+ return (1 - alpha) * x1 + alpha * x2;
+ };
+ BearingComponent.componentName = "bearing";
+ return BearingComponent;
+}(Component_1.Component));
+exports.BearingComponent = BearingComponent;
+Component_1.ComponentService.register(BearingComponent);
+exports.default = BearingComponent;
+
+
+},{"../Component":275,"../Geo":278,"../geo/ViewportCoords":389,"./utils/ComponentSize":373,"@mapbox/unitbezier":2,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],292:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Edge_1 = require("../Edge");
+var Component_1 = require("../Component");
+var CacheComponent = /** @class */ (function (_super) {
+ __extends(CacheComponent, _super);
+ function CacheComponent(name, container, navigator) {
+ return _super.call(this, name, container, navigator) || this;
+ }
+ /**
+ * Set the cache depth.
+ *
+ * Configures the cache depth. The cache depth can be different for
+ * different edge direction types.
+ *
+ * @param {ICacheDepth} depth - Cache depth structure.
+ */
+ CacheComponent.prototype.setDepth = function (depth) {
+ this.configure({ depth: depth });
+ };
+ CacheComponent.prototype._activate = function () {
+ var _this = this;
+ this._sequenceSubscription = rxjs_1.combineLatest(this._navigator.stateService.currentNode$.pipe(operators_1.switchMap(function (node) {
+ return node.sequenceEdges$;
+ }), operators_1.filter(function (status) {
+ return status.cached;
+ })), this._configuration$).pipe(operators_1.switchMap(function (nc) {
+ var status = nc[0];
+ var configuration = nc[1];
+ var sequenceDepth = Math.max(0, Math.min(4, configuration.depth.sequence));
+ var next$ = _this._cache$(status.edges, Edge_1.EdgeDirection.Next, sequenceDepth);
+ var prev$ = _this._cache$(status.edges, Edge_1.EdgeDirection.Prev, sequenceDepth);
+ return rxjs_1.merge(next$, prev$).pipe(operators_1.catchError(function (error, caught) {
+ console.error("Failed to cache sequence edges.", error);
+ return rxjs_1.empty();
+ }));
+ }))
+ .subscribe(function () { });
+ this._spatialSubscription = rxjs_1.combineLatest(this._navigator.stateService.currentNode$.pipe(operators_1.switchMap(function (node) {
+ return rxjs_1.combineLatest(rxjs_1.of(node), node.spatialEdges$.pipe(operators_1.filter(function (status) {
+ return status.cached;
+ })));
+ })), this._configuration$).pipe(operators_1.switchMap(function (_a) {
+ var _b = _a[0], node = _b[0], edgeStatus = _b[1], configuration = _a[1];
+ var edges = edgeStatus.edges;
+ var depth = configuration.depth;
+ var panoDepth = Math.max(0, Math.min(2, depth.pano));
+ var stepDepth = node.pano ? 0 : Math.max(0, Math.min(3, depth.step));
+ var turnDepth = node.pano ? 0 : Math.max(0, Math.min(1, depth.turn));
+ var pano$ = _this._cache$(edges, Edge_1.EdgeDirection.Pano, panoDepth);
+ var forward$ = _this._cache$(edges, Edge_1.EdgeDirection.StepForward, stepDepth);
+ var backward$ = _this._cache$(edges, Edge_1.EdgeDirection.StepBackward, stepDepth);
+ var left$ = _this._cache$(edges, Edge_1.EdgeDirection.StepLeft, stepDepth);
+ var right$ = _this._cache$(edges, Edge_1.EdgeDirection.StepRight, stepDepth);
+ var turnLeft$ = _this._cache$(edges, Edge_1.EdgeDirection.TurnLeft, turnDepth);
+ var turnRight$ = _this._cache$(edges, Edge_1.EdgeDirection.TurnRight, turnDepth);
+ var turnU$ = _this._cache$(edges, Edge_1.EdgeDirection.TurnU, turnDepth);
+ return rxjs_1.merge(forward$, backward$, left$, right$, pano$, turnLeft$, turnRight$, turnU$).pipe(operators_1.catchError(function (error, caught) {
+ console.error("Failed to cache spatial edges.", error);
+ return rxjs_1.empty();
+ }));
+ }))
+ .subscribe(function () { });
+ };
+ CacheComponent.prototype._deactivate = function () {
+ this._sequenceSubscription.unsubscribe();
+ this._spatialSubscription.unsubscribe();
+ };
+ CacheComponent.prototype._getDefaultConfiguration = function () {
+ return { depth: { pano: 1, sequence: 2, step: 1, turn: 0 } };
+ };
+ CacheComponent.prototype._cache$ = function (edges, direction, depth) {
+ var _this = this;
+ return rxjs_1.zip(rxjs_1.of(edges), rxjs_1.of(depth)).pipe(operators_1.expand(function (ed) {
+ var es = ed[0];
+ var d = ed[1];
+ var edgesDepths$ = [];
+ if (d > 0) {
+ for (var _i = 0, es_1 = es; _i < es_1.length; _i++) {
+ var edge = es_1[_i];
+ if (edge.data.direction === direction) {
+ edgesDepths$.push(rxjs_1.zip(_this._navigator.graphService.cacheNode$(edge.to).pipe(operators_1.mergeMap(function (n) {
+ return _this._nodeToEdges$(n, direction);
+ })), rxjs_1.of(d - 1)));
+ }
+ }
+ }
+ return rxjs_1.from(edgesDepths$).pipe(operators_1.mergeAll());
+ }), operators_1.skip(1));
+ };
+ CacheComponent.prototype._nodeToEdges$ = function (node, direction) {
+ return ([Edge_1.EdgeDirection.Next, Edge_1.EdgeDirection.Prev].indexOf(direction) > -1 ?
+ node.sequenceEdges$ :
+ node.spatialEdges$).pipe(operators_1.first(function (status) {
+ return status.cached;
+ }), operators_1.map(function (status) {
+ return status.edges;
+ }));
+ };
+ CacheComponent.componentName = "cache";
+ return CacheComponent;
+}(Component_1.Component));
+exports.CacheComponent = CacheComponent;
+Component_1.ComponentService.register(CacheComponent);
+exports.default = CacheComponent;
+
+},{"../Component":275,"../Edge":276,"rxjs":27,"rxjs/operators":225}],293:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var rxjs_1 = require("rxjs");
+var Utils_1 = require("../Utils");
+var Component = /** @class */ (function (_super) {
+ __extends(Component, _super);
+ function Component(name, container, navigator) {
+ var _this = _super.call(this) || this;
+ _this._activated$ = new rxjs_1.BehaviorSubject(false);
+ _this._configurationSubject$ = new rxjs_1.Subject();
+ _this._activated = false;
+ _this._container = container;
+ _this._name = name;
+ _this._navigator = navigator;
+ _this._configuration$ =
+ _this._configurationSubject$.pipe(operators_1.startWith(_this.defaultConfiguration), operators_1.scan(function (conf, newConf) {
+ for (var key in newConf) {
+ if (newConf.hasOwnProperty(key)) {
+ conf[key] = newConf[key];
+ }
+ }
+ return conf;
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ _this._configuration$.subscribe(function () { });
+ return _this;
+ }
+ Object.defineProperty(Component.prototype, "activated", {
+ get: function () {
+ return this._activated;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Component.prototype, "activated$", {
+ /** @ignore */
+ get: function () {
+ return this._activated$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Component.prototype, "defaultConfiguration", {
+ /**
+ * Get default configuration.
+ *
+ * @returns {TConfiguration} Default configuration for component.
+ */
+ get: function () {
+ return this._getDefaultConfiguration();
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Component.prototype, "configuration$", {
+ /** @ignore */
+ get: function () {
+ return this._configuration$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Component.prototype, "name", {
+ /**
+ * Get name.
+ *
+ * @description The name of the component. Used when interacting with the
+ * component through the Viewer's API.
+ */
+ get: function () {
+ return this._name;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Component.prototype.activate = function (conf) {
+ if (this._activated) {
+ return;
+ }
+ if (conf !== undefined) {
+ this._configurationSubject$.next(conf);
+ }
+ this._activated = true;
+ this._activate();
+ this._activated$.next(true);
+ };
+ Component.prototype.configure = function (conf) {
+ this._configurationSubject$.next(conf);
+ };
+ Component.prototype.deactivate = function () {
+ if (!this._activated) {
+ return;
+ }
+ this._activated = false;
+ this._deactivate();
+ this._container.domRenderer.clear(this._name);
+ this._container.glRenderer.clear(this._name);
+ this._activated$.next(false);
+ };
+ /**
+ * Detect the viewer's new width and height and resize the component's
+ * rendered elements accordingly if applicable.
+ *
+ * @ignore
+ */
+ Component.prototype.resize = function () { return; };
+ Component.componentName = "not_worthy";
+ return Component;
+}(Utils_1.EventEmitter));
+exports.Component = Component;
+exports.default = Component;
+
+},{"../Utils":285,"rxjs":27,"rxjs/operators":225}],294:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Error_1 = require("../Error");
+var ComponentService = /** @class */ (function () {
+ function ComponentService(container, navigator) {
+ this._components = {};
+ for (var componentName in ComponentService.registeredComponents) {
+ if (!ComponentService.registeredComponents.hasOwnProperty(componentName)) {
+ continue;
+ }
+ var component = ComponentService.registeredComponents[componentName];
+ this._components[componentName] = {
+ active: false,
+ component: new component(componentName, container, navigator),
+ };
+ }
+ this._coverComponent = new ComponentService.registeredCoverComponent("cover", container, navigator);
+ this._coverComponent.activate();
+ this._coverActivated = true;
+ }
+ ComponentService.register = function (component) {
+ if (ComponentService.registeredComponents[component.componentName] === undefined) {
+ ComponentService.registeredComponents[component.componentName] = component;
+ }
+ };
+ ComponentService.registerCover = function (coverComponent) {
+ ComponentService.registeredCoverComponent = coverComponent;
+ };
+ Object.defineProperty(ComponentService.prototype, "coverActivated", {
+ get: function () {
+ return this._coverActivated;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ComponentService.prototype.activateCover = function () {
+ if (this._coverActivated) {
+ return;
+ }
+ this._coverActivated = true;
+ for (var componentName in this._components) {
+ if (!this._components.hasOwnProperty(componentName)) {
+ continue;
+ }
+ var component = this._components[componentName];
+ if (component.active) {
+ component.component.deactivate();
+ }
+ }
+ };
+ ComponentService.prototype.deactivateCover = function () {
+ if (!this._coverActivated) {
+ return;
+ }
+ this._coverActivated = false;
+ for (var componentName in this._components) {
+ if (!this._components.hasOwnProperty(componentName)) {
+ continue;
+ }
+ var component = this._components[componentName];
+ if (component.active) {
+ component.component.activate();
+ }
+ }
+ };
+ ComponentService.prototype.activate = function (name) {
+ this._checkName(name);
+ this._components[name].active = true;
+ if (!this._coverActivated) {
+ this.get(name).activate();
+ }
+ };
+ ComponentService.prototype.configure = function (name, conf) {
+ this._checkName(name);
+ this.get(name).configure(conf);
+ };
+ ComponentService.prototype.deactivate = function (name) {
+ this._checkName(name);
+ this._components[name].active = false;
+ if (!this._coverActivated) {
+ this.get(name).deactivate();
+ }
+ };
+ ComponentService.prototype.get = function (name) {
+ return this._components[name].component;
+ };
+ ComponentService.prototype.getCover = function () {
+ return this._coverComponent;
+ };
+ ComponentService.prototype._checkName = function (name) {
+ if (!(name in this._components)) {
+ throw new Error_1.ArgumentMapillaryError("Component does not exist: " + name);
+ }
+ };
+ ComponentService.registeredComponents = {};
+ return ComponentService;
+}());
+exports.ComponentService = ComponentService;
+exports.default = ComponentService;
+
+},{"../Error":277}],295:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var Component_1 = require("../Component");
+var Utils_1 = require("../Utils");
+var Viewer_1 = require("../Viewer");
+var CoverComponent = /** @class */ (function (_super) {
+ __extends(CoverComponent, _super);
+ function CoverComponent(name, container, navigator) {
+ return _super.call(this, name, container, navigator) || this;
+ }
+ CoverComponent.prototype._activate = function () {
+ var _this = this;
+ this._configuration$.pipe(operators_1.distinctUntilChanged(undefined, function (configuration) {
+ return configuration.state;
+ }), operators_1.switchMap(function (configuration) {
+ return rxjs_1.combineLatest(rxjs_1.of(configuration.state), _this._navigator.stateService.currentNode$);
+ }), operators_1.switchMap(function (_a) {
+ var state = _a[0], node = _a[1];
+ var keySrc$ = rxjs_1.combineLatest(rxjs_1.of(node.key), node.image$.pipe(operators_1.filter(function (image) {
+ return !!image;
+ }), operators_1.map(function (image) {
+ return image.src;
+ })));
+ return state === Component_1.CoverState.Visible ? keySrc$.pipe(operators_1.first()) : keySrc$;
+ }), operators_1.distinctUntilChanged(function (_a, _b) {
+ var k1 = _a[0], s1 = _a[1];
+ var k2 = _b[0], s2 = _b[1];
+ return k1 === k2 && s1 === s2;
+ }), operators_1.map(function (_a) {
+ var key = _a[0], src = _a[1];
+ return { key: key, src: src };
+ }))
+ .subscribe(this._configurationSubject$);
+ this._renderSubscription = rxjs_1.combineLatest(this._configuration$, this._container.renderService.size$).pipe(operators_1.map(function (_a) {
+ var configuration = _a[0], size = _a[1];
+ if (!configuration.key) {
+ return { name: _this._name, vnode: vd.h("div", []) };
+ }
+ var compactClass = size.width <= 640 || size.height <= 480 ? ".CoverCompact" : "";
+ if (configuration.state === Component_1.CoverState.Hidden) {
+ var doneContainer = vd.h("div.CoverContainer.CoverDone" + compactClass, [_this._getCoverBackgroundVNode(configuration)]);
+ return { name: _this._name, vnode: doneContainer };
+ }
+ var container = vd.h("div.CoverContainer" + compactClass, [_this._getCoverButtonVNode(configuration)]);
+ return { name: _this._name, vnode: container };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ };
+ CoverComponent.prototype._deactivate = function () {
+ this._renderSubscription.unsubscribe();
+ this._keySubscription.unsubscribe();
+ };
+ CoverComponent.prototype._getDefaultConfiguration = function () {
+ return { state: Component_1.CoverState.Visible };
+ };
+ CoverComponent.prototype._getCoverButtonVNode = function (configuration) {
+ var _this = this;
+ var cover = configuration.state === Component_1.CoverState.Loading ? "div.Cover.CoverLoading" : "div.Cover";
+ var coverButton = vd.h("div.CoverButton", [vd.h("div.CoverButtonIcon", [])]);
+ var coverLogo = vd.h("a.CoverLogo", { href: Utils_1.Urls.explore, target: "_blank" }, []);
+ var coverIndicator = vd.h("div.CoverIndicator", { onclick: function () { _this.configure({ state: Component_1.CoverState.Loading }); } }, []);
+ return vd.h(cover, [
+ this._getCoverBackgroundVNode(configuration),
+ coverIndicator,
+ coverButton,
+ coverLogo,
+ ]);
+ };
+ CoverComponent.prototype._getCoverBackgroundVNode = function (conf) {
+ var url = conf.src != null ?
+ conf.src : Utils_1.Urls.thumbnail(conf.key, Viewer_1.ImageSize.Size640);
+ var properties = { style: { backgroundImage: "url(" + url + ")" } };
+ var children = [];
+ if (conf.state === Component_1.CoverState.Loading) {
+ children.push(vd.h("div.Spinner", {}, []));
+ }
+ return vd.h("div.CoverBackground", properties, children);
+ };
+ CoverComponent.componentName = "cover";
+ return CoverComponent;
+}(Component_1.Component));
+exports.CoverComponent = CoverComponent;
+Component_1.ComponentService.registerCover(CoverComponent);
+exports.default = CoverComponent;
+
+},{"../Component":275,"../Utils":285,"../Viewer":286,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],296:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var Component_1 = require("../Component");
+var DebugComponent = /** @class */ (function (_super) {
+ __extends(DebugComponent, _super);
+ function DebugComponent() {
+ var _this = _super !== null && _super.apply(this, arguments) || this;
+ _this._open$ = new rxjs_1.BehaviorSubject(false);
+ return _this;
+ }
+ DebugComponent.prototype._activate = function () {
+ var _this = this;
+ this._disposable = rxjs_1.combineLatest(this._navigator.stateService.currentState$, this._open$, this._navigator.imageLoadingService.loadstatus$).pipe(operators_1.map(function (_a) {
+ var frame = _a[0], open = _a[1], loadStatus = _a[2];
+ return { name: _this._name, vnode: _this._getDebugVNode(open, _this._getDebugInfo(frame, loadStatus)) };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ };
+ DebugComponent.prototype._deactivate = function () {
+ this._disposable.unsubscribe();
+ };
+ DebugComponent.prototype._getDefaultConfiguration = function () {
+ return {};
+ };
+ DebugComponent.prototype._getDebugInfo = function (frame, loadStatus) {
+ var ret = [];
+ ret.push(vd.h("h2", "Node"));
+ if (frame.state.currentNode) {
+ ret.push(vd.h("p", "currentNode: " + frame.state.currentNode.key));
+ }
+ if (frame.state.previousNode) {
+ ret.push(vd.h("p", "previousNode: " + frame.state.previousNode.key));
+ }
+ ret.push(vd.h("h2", "Loading"));
+ var total = 0;
+ var loaded = 0;
+ var loading = 0;
+ for (var key in loadStatus) {
+ if (!loadStatus.hasOwnProperty(key)) {
+ continue;
+ }
+ var status_1 = loadStatus[key];
+ total += status_1.loaded;
+ if (status_1.loaded !== status_1.total) {
+ loading++;
+ }
+ else {
+ loaded++;
+ }
+ }
+ ret.push(vd.h("p", "Loaded Images: " + loaded));
+ ret.push(vd.h("p", "Loading Images: " + loading));
+ ret.push(vd.h("p", "Total bytes loaded: " + total));
+ ret.push(vd.h("h2", "Camera"));
+ ret.push(vd.h("p", "camera.position.x: " + frame.state.camera.position.x));
+ ret.push(vd.h("p", "camera.position.y: " + frame.state.camera.position.y));
+ ret.push(vd.h("p", "camera.position.z: " + frame.state.camera.position.z));
+ ret.push(vd.h("p", "camera.lookat.x: " + frame.state.camera.lookat.x));
+ ret.push(vd.h("p", "camera.lookat.y: " + frame.state.camera.lookat.y));
+ ret.push(vd.h("p", "camera.lookat.z: " + frame.state.camera.lookat.z));
+ ret.push(vd.h("p", "camera.up.x: " + frame.state.camera.up.x));
+ ret.push(vd.h("p", "camera.up.y: " + frame.state.camera.up.y));
+ ret.push(vd.h("p", "camera.up.z: " + frame.state.camera.up.z));
+ return ret;
+ };
+ DebugComponent.prototype._getDebugVNode = function (open, info) {
+ if (open) {
+ return vd.h("div.Debug", {}, [
+ vd.h("h2", {}, ["Debug"]),
+ this._getDebugVNodeButton(open),
+ vd.h("pre", {}, info),
+ ]);
+ }
+ else {
+ return this._getDebugVNodeButton(open);
+ }
+ };
+ DebugComponent.prototype._getDebugVNodeButton = function (open) {
+ var buttonText = open ? "Disable Debug" : "D";
+ var buttonCssClass = open ? "" : ".DebugButtonFixed";
+ if (open) {
+ return vd.h("button.DebugButton" + buttonCssClass, { onclick: this._closeDebugElement.bind(this) }, [buttonText]);
+ }
+ else {
+ return vd.h("button.DebugButton" + buttonCssClass, { onclick: this._openDebugElement.bind(this) }, [buttonText]);
+ }
+ };
+ DebugComponent.prototype._closeDebugElement = function (open) {
+ this._open$.next(false);
+ };
+ DebugComponent.prototype._openDebugElement = function () {
+ this._open$.next(true);
+ };
+ DebugComponent.componentName = "debug";
+ return DebugComponent;
+}(Component_1.Component));
+exports.DebugComponent = DebugComponent;
+Component_1.ComponentService.register(DebugComponent);
+exports.default = DebugComponent;
+
+},{"../Component":275,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],297:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var Component_1 = require("../Component");
+var Utils_1 = require("../Utils");
+var ImageComponent = /** @class */ (function (_super) {
+ __extends(ImageComponent, _super);
+ function ImageComponent(name, container, navigator, dom) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._canvasId = container.id + "-" + _this._name;
+ _this._dom = !!dom ? dom : new Utils_1.DOM();
+ return _this;
+ }
+ ImageComponent.prototype._activate = function () {
+ var _this = this;
+ var canvasSize$ = this._container.domRenderer.element$.pipe(operators_1.map(function (element) {
+ return _this._dom.document.getElementById(_this._canvasId);
+ }), operators_1.filter(function (canvas) {
+ return !!canvas;
+ }), operators_1.map(function (canvas) {
+ var adaptableDomRenderer = canvas.parentElement;
+ var width = adaptableDomRenderer.offsetWidth;
+ var height = adaptableDomRenderer.offsetHeight;
+ return [canvas, { height: height, width: width }];
+ }), operators_1.distinctUntilChanged(function (s1, s2) {
+ return s1.height === s2.height && s1.width === s2.width;
+ }, function (_a) {
+ var canvas = _a[0], size = _a[1];
+ return size;
+ }));
+ this.drawSubscription = rxjs_1.combineLatest(canvasSize$, this._navigator.stateService.currentNode$)
+ .subscribe(function (_a) {
+ var _b = _a[0], canvas = _b[0], size = _b[1], node = _a[1];
+ canvas.width = size.width;
+ canvas.height = size.height;
+ canvas
+ .getContext("2d")
+ .drawImage(node.image, 0, 0, size.width, size.height);
+ });
+ this._container.domRenderer.renderAdaptive$.next({ name: this._name, vnode: vd.h("canvas#" + this._canvasId, []) });
+ };
+ ImageComponent.prototype._deactivate = function () {
+ this.drawSubscription.unsubscribe();
+ };
+ ImageComponent.prototype._getDefaultConfiguration = function () {
+ return {};
+ };
+ ImageComponent.componentName = "image";
+ return ImageComponent;
+}(Component_1.Component));
+exports.ImageComponent = ImageComponent;
+Component_1.ComponentService.register(ImageComponent);
+exports.default = ImageComponent;
+
+
+},{"../Component":275,"../Utils":285,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],298:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var Component_1 = require("../Component");
+var LoadingComponent = /** @class */ (function (_super) {
+ __extends(LoadingComponent, _super);
+ function LoadingComponent(name, container, navigator) {
+ return _super.call(this, name, container, navigator) || this;
+ }
+ LoadingComponent.prototype._activate = function () {
+ var _this = this;
+ this._loadingSubscription = this._navigator.loadingService.loading$.pipe(operators_1.switchMap(function (loading) {
+ return loading ?
+ _this._navigator.imageLoadingService.loadstatus$ :
+ rxjs_1.of({});
+ }), operators_1.map(function (loadStatus) {
+ var total = 0;
+ var loaded = 0;
+ for (var key in loadStatus) {
+ if (!loadStatus.hasOwnProperty(key)) {
+ continue;
+ }
+ var status_1 = loadStatus[key];
+ if (status_1.loaded !== status_1.total) {
+ loaded += status_1.loaded;
+ total += status_1.total;
+ }
+ }
+ var percentage = 100;
+ if (total !== 0) {
+ percentage = (loaded / total) * 100;
+ }
+ return { name: _this._name, vnode: _this._getBarVNode(percentage) };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ };
+ LoadingComponent.prototype._deactivate = function () {
+ this._loadingSubscription.unsubscribe();
+ };
+ LoadingComponent.prototype._getDefaultConfiguration = function () {
+ return {};
+ };
+ LoadingComponent.prototype._getBarVNode = function (percentage) {
+ var loadingBarStyle = {};
+ var loadingContainerStyle = {};
+ if (percentage !== 100) {
+ loadingBarStyle.width = percentage.toFixed(0) + "%";
+ loadingBarStyle.opacity = "1";
+ }
+ else {
+ loadingBarStyle.width = "100%";
+ loadingBarStyle.opacity = "0";
+ }
+ return vd.h("div.Loading", { style: loadingContainerStyle }, [vd.h("div.LoadingBar", { style: loadingBarStyle }, [])]);
+ };
+ LoadingComponent.componentName = "loading";
+ return LoadingComponent;
+}(Component_1.Component));
+exports.LoadingComponent = LoadingComponent;
+Component_1.ComponentService.register(LoadingComponent);
+exports.default = LoadingComponent;
+
+},{"../Component":275,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],299:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var Edge_1 = require("../Edge");
+var Error_1 = require("../Error");
+var Component_1 = require("../Component");
+/**
+ * @class NavigationComponent
+ *
+ * @classdesc Fallback navigation component for environments without WebGL support.
+ *
+ * Replaces the functionality in the Direction and Sequence components.
+ */
+var NavigationComponent = /** @class */ (function (_super) {
+ __extends(NavigationComponent, _super);
+ /** @ignore */
+ function NavigationComponent(name, container, navigator) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._seqNames = {};
+ _this._seqNames[Edge_1.EdgeDirection[Edge_1.EdgeDirection.Prev]] = "Prev";
+ _this._seqNames[Edge_1.EdgeDirection[Edge_1.EdgeDirection.Next]] = "Next";
+ _this._spaTopNames = {};
+ _this._spaTopNames[Edge_1.EdgeDirection[Edge_1.EdgeDirection.TurnLeft]] = "Turnleft";
+ _this._spaTopNames[Edge_1.EdgeDirection[Edge_1.EdgeDirection.StepLeft]] = "Left";
+ _this._spaTopNames[Edge_1.EdgeDirection[Edge_1.EdgeDirection.StepForward]] = "Forward";
+ _this._spaTopNames[Edge_1.EdgeDirection[Edge_1.EdgeDirection.StepRight]] = "Right";
+ _this._spaTopNames[Edge_1.EdgeDirection[Edge_1.EdgeDirection.TurnRight]] = "Turnright";
+ _this._spaBottomNames = {};
+ _this._spaBottomNames[Edge_1.EdgeDirection[Edge_1.EdgeDirection.TurnU]] = "Turnaround";
+ _this._spaBottomNames[Edge_1.EdgeDirection[Edge_1.EdgeDirection.StepBackward]] = "Backward";
+ return _this;
+ }
+ NavigationComponent.prototype._activate = function () {
+ var _this = this;
+ this._renderSubscription = rxjs_1.combineLatest(this._navigator.stateService.currentNode$, this._configuration$).pipe(operators_1.switchMap(function (_a) {
+ var node = _a[0], configuration = _a[1];
+ var sequenceEdges$ = configuration.sequence ?
+ node.sequenceEdges$.pipe(operators_1.map(function (status) {
+ return status.edges
+ .map(function (edge) {
+ return edge.data.direction;
+ });
+ })) :
+ rxjs_1.of([]);
+ var spatialEdges$ = !node.pano && configuration.spatial ?
+ node.spatialEdges$.pipe(operators_1.map(function (status) {
+ return status.edges
+ .map(function (edge) {
+ return edge.data.direction;
+ });
+ })) :
+ rxjs_1.of([]);
+ return rxjs_1.combineLatest(sequenceEdges$, spatialEdges$).pipe(operators_1.map(function (_a) {
+ var seq = _a[0], spa = _a[1];
+ return seq.concat(spa);
+ }));
+ }), operators_1.map(function (edgeDirections) {
+ var seqs = _this._createArrowRow(_this._seqNames, edgeDirections);
+ var spaTops = _this._createArrowRow(_this._spaTopNames, edgeDirections);
+ var spaBottoms = _this._createArrowRow(_this._spaBottomNames, edgeDirections);
+ var seqContainer = vd.h("div.NavigationSequence", seqs);
+ var spaTopContainer = vd.h("div.NavigationSpatialTop", spaTops);
+ var spaBottomContainer = vd.h("div.NavigationSpatialBottom", spaBottoms);
+ var spaContainer = vd.h("div.NavigationSpatial", [spaTopContainer, spaBottomContainer]);
+ return { name: _this._name, vnode: vd.h("div.NavigationContainer", [seqContainer, spaContainer]) };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ };
+ NavigationComponent.prototype._deactivate = function () {
+ this._renderSubscription.unsubscribe();
+ };
+ NavigationComponent.prototype._getDefaultConfiguration = function () {
+ return { sequence: true, spatial: true };
+ };
+ NavigationComponent.prototype._createArrowRow = function (arrowNames, edgeDirections) {
+ var arrows = [];
+ for (var arrowName in arrowNames) {
+ if (!(arrowNames.hasOwnProperty(arrowName))) {
+ continue;
+ }
+ var direction = Edge_1.EdgeDirection[arrowName];
+ if (edgeDirections.indexOf(direction) !== -1) {
+ arrows.push(this._createVNode(direction, arrowNames[arrowName], "visible"));
+ }
+ else {
+ arrows.push(this._createVNode(direction, arrowNames[arrowName], "hidden"));
+ }
+ }
+ return arrows;
+ };
+ NavigationComponent.prototype._createVNode = function (direction, name, visibility) {
+ var _this = this;
+ return vd.h("span.Direction.Direction" + name, {
+ onclick: function (ev) {
+ _this._navigator.moveDir$(direction)
+ .subscribe(undefined, function (error) {
+ if (!(error instanceof Error_1.AbortMapillaryError)) {
+ console.error(error);
+ }
+ });
+ },
+ style: {
+ visibility: visibility,
+ },
+ }, []);
+ };
+ NavigationComponent.componentName = "navigation";
+ return NavigationComponent;
+}(Component_1.Component));
+exports.NavigationComponent = NavigationComponent;
+Component_1.ComponentService.register(NavigationComponent);
+exports.default = NavigationComponent;
+
+},{"../Component":275,"../Edge":276,"../Error":277,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],300:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var Component_1 = require("../Component");
+var DescriptionState = /** @class */ (function () {
+ function DescriptionState() {
+ }
+ return DescriptionState;
+}());
+var RouteState = /** @class */ (function () {
+ function RouteState() {
+ }
+ return RouteState;
+}());
+var RouteTrack = /** @class */ (function () {
+ function RouteTrack() {
+ this.nodeInstructions = [];
+ this.nodeInstructionsOrdered = [];
+ }
+ return RouteTrack;
+}());
+var RouteComponent = /** @class */ (function (_super) {
+ __extends(RouteComponent, _super);
+ function RouteComponent(name, container, navigator) {
+ return _super.call(this, name, container, navigator) || this;
+ }
+ RouteComponent.prototype._activate = function () {
+ var _this = this;
+ var slowedStream$ = this._navigator.stateService.currentState$.pipe(operators_1.filter(function (frame) {
+ return (frame.id % 2) === 0;
+ }), operators_1.filter(function (frame) {
+ return frame.state.nodesAhead < 15;
+ }), operators_1.distinctUntilChanged(undefined, function (frame) {
+ return frame.state.lastNode.key;
+ }));
+ var routeTrack$ = rxjs_1.combineLatest(this.configuration$.pipe(operators_1.mergeMap(function (conf) {
+ return rxjs_1.from(conf.paths);
+ }), operators_1.distinct(function (p) {
+ return p.sequenceKey;
+ }), operators_1.mergeMap(function (path) {
+ return _this._navigator.apiV3.sequenceByKey$([path.sequenceKey]).pipe(operators_1.map(function (sequenceByKey) {
+ return sequenceByKey[path.sequenceKey];
+ }));
+ })), this.configuration$).pipe(operators_1.map(function (_a) {
+ var sequence = _a[0], conf = _a[1];
+ var i = 0;
+ var instructionPlaces = [];
+ for (var _i = 0, _b = conf.paths; _i < _b.length; _i++) {
+ var path = _b[_i];
+ if (path.sequenceKey === sequence.key) {
+ var nodeInstructions = [];
+ var saveKey = false;
+ for (var _c = 0, _d = sequence.keys; _c < _d.length; _c++) {
+ var key = _d[_c];
+ if (path.startKey === key) {
+ saveKey = true;
+ }
+ if (saveKey) {
+ var description = null;
+ for (var _e = 0, _f = path.infoKeys; _e < _f.length; _e++) {
+ var infoKey = _f[_e];
+ if (infoKey.key === key) {
+ description = infoKey.description;
+ }
+ }
+ nodeInstructions.push({ description: description, key: key });
+ }
+ if (path.stopKey === key) {
+ saveKey = false;
+ }
+ }
+ instructionPlaces.push({ nodeInstructions: nodeInstructions, place: i });
+ }
+ i++;
+ }
+ return instructionPlaces;
+ }), operators_1.scan(function (routeTrack, instructionPlaces) {
+ for (var _i = 0, instructionPlaces_1 = instructionPlaces; _i < instructionPlaces_1.length; _i++) {
+ var instructionPlace = instructionPlaces_1[_i];
+ routeTrack.nodeInstructionsOrdered[instructionPlace.place] = instructionPlace.nodeInstructions;
+ }
+ for (var place in routeTrack.nodeInstructionsOrdered) {
+ if (!routeTrack.nodeInstructionsOrdered.hasOwnProperty(place)) {
+ continue;
+ }
+ var instructionGroup = routeTrack.nodeInstructionsOrdered[place];
+ for (var _a = 0, instructionGroup_1 = instructionGroup; _a < instructionGroup_1.length; _a++) {
+ var instruction = instructionGroup_1[_a];
+ routeTrack.nodeInstructions.push(instruction);
+ }
+ }
+ return routeTrack;
+ }, new RouteTrack()));
+ var cacheNode$ = rxjs_1.combineLatest(slowedStream$, routeTrack$, this.configuration$).pipe(operators_1.map(function (_a) {
+ var frame = _a[0], routeTrack = _a[1], conf = _a[2];
+ return { conf: conf, frame: frame, routeTrack: routeTrack };
+ }), operators_1.scan(function (routeState, rtAndFrame) {
+ if (rtAndFrame.conf.playing === undefined || rtAndFrame.conf.playing) {
+ routeState.routeTrack = rtAndFrame.routeTrack;
+ routeState.currentNode = rtAndFrame.frame.state.currentNode;
+ routeState.lastNode = rtAndFrame.frame.state.lastNode;
+ routeState.playing = true;
+ }
+ else {
+ _this._navigator.stateService.cutNodes();
+ routeState.playing = false;
+ }
+ return routeState;
+ }, new RouteState()), operators_1.filter(function (routeState) {
+ return routeState.playing;
+ }), operators_1.filter(function (routeState) {
+ for (var _i = 0, _a = routeState.routeTrack.nodeInstructions; _i < _a.length; _i++) {
+ var nodeInstruction = _a[_i];
+ if (!nodeInstruction) {
+ continue;
+ }
+ if (nodeInstruction.key === routeState.lastNode.key) {
+ return true;
+ }
+ }
+ return false;
+ }), operators_1.distinctUntilChanged(undefined, function (routeState) {
+ return routeState.lastNode.key;
+ }), operators_1.mergeMap(function (routeState) {
+ var i = 0;
+ for (var _i = 0, _a = routeState.routeTrack.nodeInstructions; _i < _a.length; _i++) {
+ var nodeInstruction = _a[_i];
+ if (nodeInstruction.key === routeState.lastNode.key) {
+ break;
+ }
+ i++;
+ }
+ var nextInstruction = routeState.routeTrack.nodeInstructions[i + 1];
+ if (!nextInstruction) {
+ return rxjs_1.of(null);
+ }
+ return _this._navigator.graphService.cacheNode$(nextInstruction.key);
+ }));
+ this._disposable = rxjs_1.combineLatest(cacheNode$, this.configuration$).pipe(operators_1.map(function (_a) {
+ var node = _a[0], conf = _a[1];
+ return { conf: conf, node: node };
+ }), operators_1.filter(function (cAN) {
+ return cAN.node !== null && cAN.conf.playing;
+ }), operators_1.pluck("node"))
+ .subscribe(this._navigator.stateService.appendNode$);
+ this._disposableDescription = rxjs_1.combineLatest(this._navigator.stateService.currentNode$, routeTrack$, this.configuration$).pipe(operators_1.map(function (_a) {
+ var node = _a[0], routeTrack = _a[1], conf = _a[2];
+ if (conf.playing !== undefined && !conf.playing) {
+ return "quit";
+ }
+ var description = null;
+ for (var _i = 0, _b = routeTrack.nodeInstructions; _i < _b.length; _i++) {
+ var nodeInstruction = _b[_i];
+ if (nodeInstruction.key === node.key) {
+ description = nodeInstruction.description;
+ break;
+ }
+ }
+ return description;
+ }), operators_1.scan(function (descriptionState, description) {
+ if (description !== descriptionState.description && description !== null) {
+ descriptionState.description = description;
+ descriptionState.showsLeft = 6;
+ }
+ else {
+ descriptionState.showsLeft--;
+ }
+ if (description === "quit") {
+ descriptionState.description = null;
+ }
+ return descriptionState;
+ }, new DescriptionState()), operators_1.map(function (descriptionState) {
+ if (descriptionState.showsLeft > 0 && descriptionState.description) {
+ return { name: _this._name, vnode: _this._getRouteAnnotationNode(descriptionState.description) };
+ }
+ else {
+ return { name: _this._name, vnode: vd.h("div", []) };
+ }
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ };
+ RouteComponent.prototype._deactivate = function () {
+ this._disposable.unsubscribe();
+ this._disposableDescription.unsubscribe();
+ };
+ RouteComponent.prototype._getDefaultConfiguration = function () {
+ return {};
+ };
+ RouteComponent.prototype.play = function () {
+ this.configure({ playing: true });
+ };
+ RouteComponent.prototype.stop = function () {
+ this.configure({ playing: false });
+ };
+ RouteComponent.prototype._getRouteAnnotationNode = function (description) {
+ return vd.h("div.RouteFrame", {}, [
+ vd.h("p", { textContent: description }, []),
+ ]);
+ };
+ RouteComponent.componentName = "route";
+ return RouteComponent;
+}(Component_1.Component));
+exports.RouteComponent = RouteComponent;
+Component_1.ComponentService.register(RouteComponent);
+exports.default = RouteComponent;
+
+},{"../Component":275,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],301:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../Component");
+var StatsComponent = /** @class */ (function (_super) {
+ __extends(StatsComponent, _super);
+ function StatsComponent(name, container, navigator, scheduler) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._scheduler = scheduler;
+ return _this;
+ }
+ StatsComponent.prototype._activate = function () {
+ var _this = this;
+ this._sequenceSubscription = this._navigator.stateService.currentNode$.pipe(operators_1.scan(function (keys, node) {
+ var sKey = node.sequenceKey;
+ keys.report = [];
+ if (!(sKey in keys.reported)) {
+ keys.report = [sKey];
+ keys.reported[sKey] = true;
+ }
+ return keys;
+ }, { report: [], reported: {} }), operators_1.filter(function (keys) {
+ return keys.report.length > 0;
+ }), operators_1.mergeMap(function (keys) {
+ return _this._navigator.apiV3.sequenceViewAdd$(keys.report).pipe(operators_1.catchError(function (error, caught) {
+ console.error("Failed to report sequence stats (" + keys.report + ")", error);
+ return rxjs_1.empty();
+ }));
+ }))
+ .subscribe(function () { });
+ this._imageSubscription = this._navigator.stateService.currentNode$.pipe(operators_1.map(function (node) {
+ return node.key;
+ })).pipe(operators_1.buffer(this._navigator.stateService.currentNode$.pipe(operators_1.debounceTime(5000, this._scheduler))), operators_1.scan(function (keys, newKeys) {
+ keys.report = [];
+ for (var _i = 0, newKeys_1 = newKeys; _i < newKeys_1.length; _i++) {
+ var key = newKeys_1[_i];
+ if (!(key in keys.reported)) {
+ keys.report.push(key);
+ keys.reported[key] = true;
+ }
+ }
+ return keys;
+ }, { report: [], reported: {} }), operators_1.filter(function (keys) {
+ return keys.report.length > 0;
+ }), operators_1.mergeMap(function (keys) {
+ return _this._navigator.apiV3.imageViewAdd$(keys.report).pipe(operators_1.catchError(function (error, caught) {
+ console.error("Failed to report image stats (" + keys.report + ")", error);
+ return rxjs_1.empty();
+ }));
+ }))
+ .subscribe(function () { });
+ };
+ StatsComponent.prototype._deactivate = function () {
+ this._sequenceSubscription.unsubscribe();
+ this._imageSubscription.unsubscribe();
+ };
+ StatsComponent.prototype._getDefaultConfiguration = function () {
+ return {};
+ };
+ StatsComponent.componentName = "stats";
+ return StatsComponent;
+}(Component_1.Component));
+exports.StatsComponent = StatsComponent;
+Component_1.ComponentService.register(StatsComponent);
+exports.default = StatsComponent;
+
+},{"../Component":275,"rxjs":27,"rxjs/operators":225}],302:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var vd = require("virtual-dom");
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+/**
+ * @class DirectionComponent
+ * @classdesc Component showing navigation arrows for steps and turns.
+ */
+var DirectionComponent = /** @class */ (function (_super) {
+ __extends(DirectionComponent, _super);
+ function DirectionComponent(name, container, navigator, directionDOMRenderer) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._renderer = !!directionDOMRenderer ?
+ directionDOMRenderer :
+ new Component_1.DirectionDOMRenderer(_this.defaultConfiguration, { height: container.element.offsetHeight, width: container.element.offsetWidth });
+ _this._hoveredKeySubject$ = new rxjs_1.Subject();
+ _this._hoveredKey$ = _this._hoveredKeySubject$.pipe(operators_1.share());
+ return _this;
+ }
+ Object.defineProperty(DirectionComponent.prototype, "hoveredKey$", {
+ /**
+ * Get hovered key observable.
+ *
+ * @description An observable emitting the key of the node for the direction
+ * arrow that is being hovered. When the mouse leaves a direction arrow null
+ * is emitted.
+ *
+ * @returns {Observable<string>}
+ */
+ get: function () {
+ return this._hoveredKey$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Set highlight key.
+ *
+ * @description The arrow pointing towards the node corresponding to the
+ * highlight key will be highlighted.
+ *
+ * @param {string} highlightKey Key of node to be highlighted if existing
+ * among arrows.
+ */
+ DirectionComponent.prototype.setHighlightKey = function (highlightKey) {
+ this.configure({ highlightKey: highlightKey });
+ };
+ /**
+ * Set min width of container element.
+ *
+ * @description Set min width of the non transformed container element holding
+ * the navigation arrows. If the min width is larger than the max width the
+ * min width value will be used.
+ *
+ * The container element is automatically resized when the resize
+ * method on the Viewer class is called.
+ *
+ * @param {number} minWidth
+ */
+ DirectionComponent.prototype.setMinWidth = function (minWidth) {
+ this.configure({ minWidth: minWidth });
+ };
+ /**
+ * Set max width of container element.
+ *
+ * @description Set max width of the non transformed container element holding
+ * the navigation arrows. If the min width is larger than the max width the
+ * min width value will be used.
+ *
+ * The container element is automatically resized when the resize
+ * method on the Viewer class is called.
+ *
+ * @param {number} minWidth
+ */
+ DirectionComponent.prototype.setMaxWidth = function (maxWidth) {
+ this.configure({ maxWidth: maxWidth });
+ };
+ DirectionComponent.prototype._activate = function () {
+ var _this = this;
+ this._configurationSubscription = this._configuration$
+ .subscribe(function (configuration) {
+ _this._renderer.setConfiguration(configuration);
+ });
+ this._resizeSubscription = this._container.renderService.size$
+ .subscribe(function (size) {
+ _this._renderer.resize(size);
+ });
+ this._nodeSubscription = this._navigator.stateService.currentNode$.pipe(operators_1.tap(function (node) {
+ _this._container.domRenderer.render$.next({ name: _this._name, vnode: vd.h("div", {}, []) });
+ _this._renderer.setNode(node);
+ }), operators_1.withLatestFrom(this._configuration$), operators_1.switchMap(function (_a) {
+ var node = _a[0], configuration = _a[1];
+ return rxjs_1.combineLatest(node.spatialEdges$, configuration.distinguishSequence ?
+ _this._navigator.graphService
+ .cacheSequence$(node.sequenceKey).pipe(operators_1.catchError(function (error, caught) {
+ console.error("Failed to cache sequence (" + node.sequenceKey + ")", error);
+ return rxjs_1.of(null);
+ })) :
+ rxjs_1.of(null));
+ }))
+ .subscribe(function (_a) {
+ var edgeStatus = _a[0], sequence = _a[1];
+ _this._renderer.setEdges(edgeStatus, sequence);
+ });
+ this._renderCameraSubscription = this._container.renderService.renderCameraFrame$.pipe(operators_1.tap(function (renderCamera) {
+ _this._renderer.setRenderCamera(renderCamera);
+ }), operators_1.map(function () {
+ return _this._renderer;
+ }), operators_1.filter(function (renderer) {
+ return renderer.needsRender;
+ }), operators_1.map(function (renderer) {
+ return { name: _this._name, vnode: renderer.render(_this._navigator) };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ this._hoveredKeySubscription = rxjs_1.combineLatest(this._container.domRenderer.element$, this._container.renderService.renderCamera$, this._container.mouseService.mouseMove$.pipe(operators_1.startWith(null)), this._container.mouseService.mouseUp$.pipe(operators_1.startWith(null))).pipe(operators_1.map(function (_a) {
+ var element = _a[0];
+ var elements = element.getElementsByClassName("DirectionsPerspective");
+ for (var i = 0; i < elements.length; i++) {
+ var hovered = elements.item(i).querySelector(":hover");
+ if (hovered != null && hovered.hasAttribute("data-key")) {
+ return hovered.getAttribute("data-key");
+ }
+ }
+ return null;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(this._hoveredKeySubject$);
+ this._emitHoveredKeySubscription = this._hoveredKey$
+ .subscribe(function (key) {
+ _this.fire(DirectionComponent.hoveredkeychanged, key);
+ });
+ };
+ DirectionComponent.prototype._deactivate = function () {
+ this._configurationSubscription.unsubscribe();
+ this._emitHoveredKeySubscription.unsubscribe();
+ this._hoveredKeySubscription.unsubscribe();
+ this._nodeSubscription.unsubscribe();
+ this._renderCameraSubscription.unsubscribe();
+ };
+ DirectionComponent.prototype._getDefaultConfiguration = function () {
+ return {
+ distinguishSequence: false,
+ maxWidth: 460,
+ minWidth: 260,
+ };
+ };
+ /** @inheritdoc */
+ DirectionComponent.componentName = "direction";
+ /**
+ * Event fired when the hovered key changes.
+ *
+ * @description Emits the key of the node for the direction
+ * arrow that is being hovered. When the mouse leaves a
+ * direction arrow null is emitted.
+ *
+ * @event DirectionComponent#hoveredkeychanged
+ * @type {string} The hovered key, null if no key is hovered.
+ */
+ DirectionComponent.hoveredkeychanged = "hoveredkeychanged";
+ return DirectionComponent;
+}(Component_1.Component));
+exports.DirectionComponent = DirectionComponent;
+Component_1.ComponentService.register(DirectionComponent);
+exports.default = DirectionComponent;
+
+
+},{"../../Component":275,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],303:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Geo_1 = require("../../Geo");
+/**
+ * @class DirectionDOMCalculator
+ * @classdesc Helper class for calculating DOM CSS properties.
+ */
+var DirectionDOMCalculator = /** @class */ (function () {
+ function DirectionDOMCalculator(configuration, size) {
+ this._spatial = new Geo_1.Spatial();
+ this._minThresholdWidth = 320;
+ this._maxThresholdWidth = 1480;
+ this._minThresholdHeight = 240;
+ this._maxThresholdHeight = 820;
+ this._configure(configuration);
+ this._resize(size);
+ this._reset();
+ }
+ Object.defineProperty(DirectionDOMCalculator.prototype, "minWidth", {
+ get: function () {
+ return this._minWidth;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "maxWidth", {
+ get: function () {
+ return this._maxWidth;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "containerWidth", {
+ get: function () {
+ return this._containerWidth;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "containerWidthCss", {
+ get: function () {
+ return this._containerWidthCss;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "containerMarginCss", {
+ get: function () {
+ return this._containerMarginCss;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "containerLeftCss", {
+ get: function () {
+ return this._containerLeftCss;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "containerHeight", {
+ get: function () {
+ return this._containerHeight;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "containerHeightCss", {
+ get: function () {
+ return this._containerHeightCss;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "containerBottomCss", {
+ get: function () {
+ return this._containerBottomCss;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "stepCircleSize", {
+ get: function () {
+ return this._stepCircleSize;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "stepCircleSizeCss", {
+ get: function () {
+ return this._stepCircleSizeCss;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "stepCircleMarginCss", {
+ get: function () {
+ return this._stepCircleMarginCss;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "turnCircleSize", {
+ get: function () {
+ return this._turnCircleSize;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "turnCircleSizeCss", {
+ get: function () {
+ return this._turnCircleSizeCss;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "outerRadius", {
+ get: function () {
+ return this._outerRadius;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "innerRadius", {
+ get: function () {
+ return this._innerRadius;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(DirectionDOMCalculator.prototype, "shadowOffset", {
+ get: function () {
+ return this._shadowOffset;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Configures the min and max width values.
+ *
+ * @param {IDirectionConfiguration} configuration Configuration
+ * with min and max width values.
+ */
+ DirectionDOMCalculator.prototype.configure = function (configuration) {
+ this._configure(configuration);
+ this._reset();
+ };
+ /**
+ * Resizes all properties according to the width and height
+ * of the size object.
+ *
+ * @param {ISize} size The size of the container element.
+ */
+ DirectionDOMCalculator.prototype.resize = function (size) {
+ this._resize(size);
+ this._reset();
+ };
+ /**
+ * Calculates the coordinates on the unit circle for an angle.
+ *
+ * @param {number} angle Angle in radians.
+ * @returns {Array<number>} The x and y coordinates on the unit circle.
+ */
+ DirectionDOMCalculator.prototype.angleToCoordinates = function (angle) {
+ return [Math.cos(angle), Math.sin(angle)];
+ };
+ /**
+ * Calculates the coordinates on the unit circle for the
+ * relative angle between the first and second angle.
+ *
+ * @param {number} first Angle in radians.
+ * @param {number} second Angle in radians.
+ * @returns {Array<number>} The x and y coordinates on the unit circle
+ * for the relative angle between the first and second angle.
+ */
+ DirectionDOMCalculator.prototype.relativeAngleToCoordiantes = function (first, second) {
+ var relativeAngle = this._spatial.wrapAngle(first - second);
+ return this.angleToCoordinates(relativeAngle);
+ };
+ DirectionDOMCalculator.prototype._configure = function (configuration) {
+ this._minWidth = configuration.minWidth;
+ this._maxWidth = this._getMaxWidth(configuration.minWidth, configuration.maxWidth);
+ };
+ DirectionDOMCalculator.prototype._resize = function (size) {
+ this._elementWidth = size.width;
+ this._elementHeight = size.height;
+ };
+ DirectionDOMCalculator.prototype._reset = function () {
+ this._containerWidth = this._getContainerWidth(this._elementWidth, this._elementHeight);
+ this._containerHeight = this._getContainerHeight(this.containerWidth);
+ this._stepCircleSize = this._getStepCircleDiameter(this._containerHeight);
+ this._turnCircleSize = this._getTurnCircleDiameter(this.containerHeight);
+ this._outerRadius = this._getOuterRadius(this._containerHeight);
+ this._innerRadius = this._getInnerRadius(this._containerHeight);
+ this._shadowOffset = 3;
+ this._containerWidthCss = this._numberToCssPixels(this._containerWidth);
+ this._containerMarginCss = this._numberToCssPixels(-0.5 * this._containerWidth);
+ this._containerLeftCss = this._numberToCssPixels(Math.floor(0.5 * this._elementWidth));
+ this._containerHeightCss = this._numberToCssPixels(this._containerHeight);
+ this._containerBottomCss = this._numberToCssPixels(Math.floor(-0.08 * this._containerHeight));
+ this._stepCircleSizeCss = this._numberToCssPixels(this._stepCircleSize);
+ this._stepCircleMarginCss = this._numberToCssPixels(-0.5 * this._stepCircleSize);
+ this._turnCircleSizeCss = this._numberToCssPixels(this._turnCircleSize);
+ };
+ DirectionDOMCalculator.prototype._getContainerWidth = function (elementWidth, elementHeight) {
+ var relativeWidth = (elementWidth - this._minThresholdWidth) / (this._maxThresholdWidth - this._minThresholdWidth);
+ var relativeHeight = (elementHeight - this._minThresholdHeight) / (this._maxThresholdHeight - this._minThresholdHeight);
+ var coeff = Math.max(0, Math.min(1, Math.min(relativeWidth, relativeHeight)));
+ coeff = 0.04 * Math.round(25 * coeff);
+ return this._minWidth + coeff * (this._maxWidth - this._minWidth);
+ };
+ DirectionDOMCalculator.prototype._getContainerHeight = function (containerWidth) {
+ return 0.77 * containerWidth;
+ };
+ DirectionDOMCalculator.prototype._getStepCircleDiameter = function (containerHeight) {
+ return 0.34 * containerHeight;
+ };
+ DirectionDOMCalculator.prototype._getTurnCircleDiameter = function (containerHeight) {
+ return 0.3 * containerHeight;
+ };
+ DirectionDOMCalculator.prototype._getOuterRadius = function (containerHeight) {
+ return 0.31 * containerHeight;
+ };
+ DirectionDOMCalculator.prototype._getInnerRadius = function (containerHeight) {
+ return 0.125 * containerHeight;
+ };
+ DirectionDOMCalculator.prototype._numberToCssPixels = function (value) {
+ return value + "px";
+ };
+ DirectionDOMCalculator.prototype._getMaxWidth = function (value, minWidth) {
+ return value > minWidth ? value : minWidth;
+ };
+ return DirectionDOMCalculator;
+}());
+exports.DirectionDOMCalculator = DirectionDOMCalculator;
+exports.default = DirectionDOMCalculator;
+
+
+},{"../../Geo":278}],304:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var vd = require("virtual-dom");
+var Component_1 = require("../../Component");
+var Edge_1 = require("../../Edge");
+var Error_1 = require("../../Error");
+var Geo_1 = require("../../Geo");
+/**
+ * @class DirectionDOMRenderer
+ * @classdesc DOM renderer for direction arrows.
+ */
+var DirectionDOMRenderer = /** @class */ (function () {
+ function DirectionDOMRenderer(configuration, size) {
+ this._isEdge = false;
+ this._spatial = new Geo_1.Spatial();
+ this._calculator = new Component_1.DirectionDOMCalculator(configuration, size);
+ this._node = null;
+ this._rotation = { phi: 0, theta: 0 };
+ this._epsilon = 0.5 * Math.PI / 180;
+ this._highlightKey = null;
+ this._distinguishSequence = false;
+ this._needsRender = false;
+ this._stepEdges = [];
+ this._turnEdges = [];
+ this._panoEdges = [];
+ this._sequenceEdgeKeys = [];
+ this._stepDirections = [
+ Edge_1.EdgeDirection.StepForward,
+ Edge_1.EdgeDirection.StepBackward,
+ Edge_1.EdgeDirection.StepLeft,
+ Edge_1.EdgeDirection.StepRight,
+ ];
+ this._turnDirections = [
+ Edge_1.EdgeDirection.TurnLeft,
+ Edge_1.EdgeDirection.TurnRight,
+ Edge_1.EdgeDirection.TurnU,
+ ];
+ this._turnNames = {};
+ this._turnNames[Edge_1.EdgeDirection.TurnLeft] = "TurnLeft";
+ this._turnNames[Edge_1.EdgeDirection.TurnRight] = "TurnRight";
+ this._turnNames[Edge_1.EdgeDirection.TurnU] = "TurnAround";
+ // detects IE 8-11, then Edge 20+.
+ var isIE = !!document.documentMode;
+ this._isEdge = !isIE && !!window.StyleMedia;
+ }
+ Object.defineProperty(DirectionDOMRenderer.prototype, "needsRender", {
+ /**
+ * Get needs render.
+ *
+ * @returns {boolean} Value indicating whether render should be called.
+ */
+ get: function () {
+ return this._needsRender;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Renders virtual DOM elements.
+ *
+ * @description Calling render resets the needs render property.
+ */
+ DirectionDOMRenderer.prototype.render = function (navigator) {
+ this._needsRender = false;
+ var rotation = this._rotation;
+ var steps = [];
+ var turns = [];
+ if (this._node.pano) {
+ steps = steps.concat(this._createPanoArrows(navigator, rotation));
+ }
+ else {
+ steps = steps.concat(this._createPerspectiveToPanoArrows(navigator, rotation));
+ steps = steps.concat(this._createStepArrows(navigator, rotation));
+ turns = turns.concat(this._createTurnArrows(navigator));
+ }
+ return this._getContainer(steps, turns, rotation);
+ };
+ DirectionDOMRenderer.prototype.setEdges = function (edgeStatus, sequence) {
+ this._setEdges(edgeStatus, sequence);
+ this._setNeedsRender();
+ };
+ /**
+ * Set node for which to show edges.
+ *
+ * @param {Node} node
+ */
+ DirectionDOMRenderer.prototype.setNode = function (node) {
+ this._node = node;
+ this._clearEdges();
+ this._setNeedsRender();
+ };
+ /**
+ * Set the render camera to use for calculating rotations.
+ *
+ * @param {RenderCamera} renderCamera
+ */
+ DirectionDOMRenderer.prototype.setRenderCamera = function (renderCamera) {
+ var rotation = renderCamera.rotation;
+ if (Math.abs(rotation.phi - this._rotation.phi) < this._epsilon) {
+ return;
+ }
+ this._rotation = rotation;
+ this._setNeedsRender();
+ };
+ /**
+ * Set configuration values.
+ *
+ * @param {IDirectionConfiguration} configuration
+ */
+ DirectionDOMRenderer.prototype.setConfiguration = function (configuration) {
+ var needsRender = false;
+ if (this._highlightKey !== configuration.highlightKey ||
+ this._distinguishSequence !== configuration.distinguishSequence) {
+ this._highlightKey = configuration.highlightKey;
+ this._distinguishSequence = configuration.distinguishSequence;
+ needsRender = true;
+ }
+ if (this._calculator.minWidth !== configuration.minWidth ||
+ this._calculator.maxWidth !== configuration.maxWidth) {
+ this._calculator.configure(configuration);
+ needsRender = true;
+ }
+ if (needsRender) {
+ this._setNeedsRender();
+ }
+ };
+ /**
+ * Detect the element's width and height and resize
+ * elements accordingly.
+ *
+ * @param {ISize} size Size of vßiewer container element.
+ */
+ DirectionDOMRenderer.prototype.resize = function (size) {
+ this._calculator.resize(size);
+ this._setNeedsRender();
+ };
+ DirectionDOMRenderer.prototype._setNeedsRender = function () {
+ if (this._node != null) {
+ this._needsRender = true;
+ }
+ };
+ DirectionDOMRenderer.prototype._clearEdges = function () {
+ this._stepEdges = [];
+ this._turnEdges = [];
+ this._panoEdges = [];
+ this._sequenceEdgeKeys = [];
+ };
+ DirectionDOMRenderer.prototype._setEdges = function (edgeStatus, sequence) {
+ this._stepEdges = [];
+ this._turnEdges = [];
+ this._panoEdges = [];
+ this._sequenceEdgeKeys = [];
+ for (var _i = 0, _a = edgeStatus.edges; _i < _a.length; _i++) {
+ var edge = _a[_i];
+ var direction = edge.data.direction;
+ if (this._stepDirections.indexOf(direction) > -1) {
+ this._stepEdges.push(edge);
+ continue;
+ }
+ if (this._turnDirections.indexOf(direction) > -1) {
+ this._turnEdges.push(edge);
+ continue;
+ }
+ if (edge.data.direction === Edge_1.EdgeDirection.Pano) {
+ this._panoEdges.push(edge);
+ }
+ }
+ if (this._distinguishSequence && sequence != null) {
+ var edges = this._panoEdges
+ .concat(this._stepEdges)
+ .concat(this._turnEdges);
+ for (var _b = 0, edges_1 = edges; _b < edges_1.length; _b++) {
+ var edge = edges_1[_b];
+ var edgeKey = edge.to;
+ for (var _c = 0, _d = sequence.keys; _c < _d.length; _c++) {
+ var sequenceKey = _d[_c];
+ if (sequenceKey === edgeKey) {
+ this._sequenceEdgeKeys.push(edgeKey);
+ break;
+ }
+ }
+ }
+ }
+ };
+ DirectionDOMRenderer.prototype._createPanoArrows = function (navigator, rotation) {
+ var arrows = [];
+ for (var _i = 0, _a = this._panoEdges; _i < _a.length; _i++) {
+ var panoEdge = _a[_i];
+ arrows.push(this._createVNodeByKey(navigator, panoEdge.to, panoEdge.data.worldMotionAzimuth, rotation, this._calculator.outerRadius, "DirectionsArrowPano"));
+ }
+ for (var _b = 0, _c = this._stepEdges; _b < _c.length; _b++) {
+ var stepEdge = _c[_b];
+ arrows.push(this._createPanoToPerspectiveArrow(navigator, stepEdge.to, stepEdge.data.worldMotionAzimuth, rotation, stepEdge.data.direction));
+ }
+ return arrows;
+ };
+ DirectionDOMRenderer.prototype._createPanoToPerspectiveArrow = function (navigator, key, azimuth, rotation, direction) {
+ var threshold = Math.PI / 8;
+ var relativePhi = rotation.phi;
+ switch (direction) {
+ case Edge_1.EdgeDirection.StepBackward:
+ relativePhi = rotation.phi - Math.PI;
+ break;
+ case Edge_1.EdgeDirection.StepLeft:
+ relativePhi = rotation.phi + Math.PI / 2;
+ break;
+ case Edge_1.EdgeDirection.StepRight:
+ relativePhi = rotation.phi - Math.PI / 2;
+ break;
+ default:
+ break;
+ }
+ if (Math.abs(this._spatial.wrapAngle(azimuth - relativePhi)) < threshold) {
+ return this._createVNodeByKey(navigator, key, azimuth, rotation, this._calculator.outerRadius, "DirectionsArrowStep");
+ }
+ return this._createVNodeDisabled(key, azimuth, rotation);
+ };
+ DirectionDOMRenderer.prototype._createPerspectiveToPanoArrows = function (navigator, rotation) {
+ var arrows = [];
+ for (var _i = 0, _a = this._panoEdges; _i < _a.length; _i++) {
+ var panoEdge = _a[_i];
+ arrows.push(this._createVNodeByKey(navigator, panoEdge.to, panoEdge.data.worldMotionAzimuth, rotation, this._calculator.innerRadius, "DirectionsArrowPano", true));
+ }
+ return arrows;
+ };
+ DirectionDOMRenderer.prototype._createStepArrows = function (navigator, rotation) {
+ var arrows = [];
+ for (var _i = 0, _a = this._stepEdges; _i < _a.length; _i++) {
+ var stepEdge = _a[_i];
+ arrows.push(this._createVNodeByDirection(navigator, stepEdge.to, stepEdge.data.worldMotionAzimuth, rotation, stepEdge.data.direction));
+ }
+ return arrows;
+ };
+ DirectionDOMRenderer.prototype._createTurnArrows = function (navigator) {
+ var turns = [];
+ for (var _i = 0, _a = this._turnEdges; _i < _a.length; _i++) {
+ var turnEdge = _a[_i];
+ var direction = turnEdge.data.direction;
+ var name_1 = this._turnNames[direction];
+ turns.push(this._createVNodeByTurn(navigator, turnEdge.to, name_1, direction));
+ }
+ return turns;
+ };
+ DirectionDOMRenderer.prototype._createVNodeByKey = function (navigator, key, azimuth, rotation, offset, className, shiftVertically) {
+ var onClick = function (e) {
+ navigator.moveToKey$(key)
+ .subscribe(undefined, function (error) {
+ if (!(error instanceof Error_1.AbortMapillaryError)) {
+ console.error(error);
+ }
+ });
+ };
+ return this._createVNode(key, azimuth, rotation, offset, className, "DirectionsCircle", onClick, shiftVertically);
+ };
+ DirectionDOMRenderer.prototype._createVNodeByDirection = function (navigator, key, azimuth, rotation, direction) {
+ var onClick = function (e) {
+ navigator.moveDir$(direction)
+ .subscribe(undefined, function (error) {
+ if (!(error instanceof Error_1.AbortMapillaryError)) {
+ console.error(error);
+ }
+ });
+ };
+ return this._createVNode(key, azimuth, rotation, this._calculator.outerRadius, "DirectionsArrowStep", "DirectionsCircle", onClick);
+ };
+ DirectionDOMRenderer.prototype._createVNodeByTurn = function (navigator, key, className, direction) {
+ var onClick = function (e) {
+ navigator.moveDir$(direction)
+ .subscribe(undefined, function (error) {
+ if (!(error instanceof Error_1.AbortMapillaryError)) {
+ console.error(error);
+ }
+ });
+ };
+ var style = {
+ height: this._calculator.turnCircleSizeCss,
+ transform: "rotate(0)",
+ width: this._calculator.turnCircleSizeCss,
+ };
+ switch (direction) {
+ case Edge_1.EdgeDirection.TurnLeft:
+ style.left = "5px";
+ style.top = "5px";
+ break;
+ case Edge_1.EdgeDirection.TurnRight:
+ style.right = "5px";
+ style.top = "5px";
+ break;
+ case Edge_1.EdgeDirection.TurnU:
+ style.left = "5px";
+ style.bottom = "5px";
+ break;
+ default:
+ break;
+ }
+ var circleProperties = {
+ attributes: {
+ "data-key": key,
+ },
+ onclick: onClick,
+ style: style,
+ };
+ var circleClassName = "TurnCircle";
+ if (this._sequenceEdgeKeys.indexOf(key) > -1) {
+ circleClassName += "Sequence";
+ }
+ if (this._highlightKey === key) {
+ circleClassName += "Highlight";
+ }
+ var turn = vd.h("div." + className, {}, []);
+ return vd.h("div." + circleClassName, circleProperties, [turn]);
+ };
+ DirectionDOMRenderer.prototype._createVNodeDisabled = function (key, azimuth, rotation) {
+ return this._createVNode(key, azimuth, rotation, this._calculator.outerRadius, "DirectionsArrowDisabled", "DirectionsCircleDisabled");
+ };
+ DirectionDOMRenderer.prototype._createVNode = function (key, azimuth, rotation, radius, className, circleClassName, onClick, shiftVertically) {
+ var translation = this._calculator.angleToCoordinates(azimuth - rotation.phi);
+ // rotate 90 degrees clockwise and flip over X-axis
+ var translationX = Math.round(-radius * translation[1] + 0.5 * this._calculator.containerWidth);
+ var translationY = Math.round(-radius * translation[0] + 0.5 * this._calculator.containerHeight);
+ var shadowTranslation = this._calculator.relativeAngleToCoordiantes(azimuth, rotation.phi);
+ var shadowOffset = this._calculator.shadowOffset;
+ var shadowTranslationX = -shadowOffset * shadowTranslation[1];
+ var shadowTranslationY = shadowOffset * shadowTranslation[0];
+ var filter = "drop-shadow(" + shadowTranslationX + "px " + shadowTranslationY + "px 1px rgba(0,0,0,0.8))";
+ var properties = {
+ style: {
+ "-webkit-filter": filter,
+ filter: filter,
+ },
+ };
+ var chevron = vd.h("div." + className, properties, []);
+ var azimuthDeg = -this._spatial.radToDeg(azimuth - rotation.phi);
+ var circleTransform = shiftVertically ?
+ "translate(" + translationX + "px, " + translationY + "px) rotate(" + azimuthDeg + "deg) translateZ(-0.01px)" :
+ "translate(" + translationX + "px, " + translationY + "px) rotate(" + azimuthDeg + "deg)";
+ var circleProperties = {
+ attributes: { "data-key": key },
+ onclick: onClick,
+ style: {
+ height: this._calculator.stepCircleSizeCss,
+ marginLeft: this._calculator.stepCircleMarginCss,
+ marginTop: this._calculator.stepCircleMarginCss,
+ transform: circleTransform,
+ width: this._calculator.stepCircleSizeCss,
+ },
+ };
+ if (this._sequenceEdgeKeys.indexOf(key) > -1) {
+ circleClassName += "Sequence";
+ }
+ if (this._highlightKey === key) {
+ circleClassName += "Highlight";
+ }
+ return vd.h("div." + circleClassName, circleProperties, [chevron]);
+ };
+ DirectionDOMRenderer.prototype._getContainer = function (steps, turns, rotation) {
+ // edge does not handle hover on perspective transforms.
+ var transform = this._isEdge ?
+ "rotateX(60deg)" :
+ "perspective(" + this._calculator.containerWidthCss + ") rotateX(60deg)";
+ var properties = {
+ oncontextmenu: function (event) { event.preventDefault(); },
+ style: {
+ bottom: this._calculator.containerBottomCss,
+ height: this._calculator.containerHeightCss,
+ left: this._calculator.containerLeftCss,
+ marginLeft: this._calculator.containerMarginCss,
+ transform: transform,
+ width: this._calculator.containerWidthCss,
+ },
+ };
+ return vd.h("div.DirectionsPerspective", properties, turns.concat(steps));
+ };
+ return DirectionDOMRenderer;
+}());
+exports.DirectionDOMRenderer = DirectionDOMRenderer;
+exports.default = DirectionDOMRenderer;
+
+
+},{"../../Component":275,"../../Edge":276,"../../Error":277,"../../Geo":278,"virtual-dom":231}],305:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+var Viewer_1 = require("../../Viewer");
+var Render_1 = require("../../Render");
+var Tiles_1 = require("../../Tiles");
+var Utils_1 = require("../../Utils");
+var ViewportCoords_1 = require("../../geo/ViewportCoords");
+var Spatial_1 = require("../../geo/Spatial");
+var ImagePlaneComponent = /** @class */ (function (_super) {
+ __extends(ImagePlaneComponent, _super);
+ function ImagePlaneComponent(name, container, navigator) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._imageTileLoader = new Tiles_1.ImageTileLoader(Utils_1.Urls.tileScheme, Utils_1.Urls.tileDomain, Utils_1.Urls.origin);
+ _this._roiCalculator = new Tiles_1.RegionOfInterestCalculator();
+ _this._rendererOperation$ = new rxjs_1.Subject();
+ _this._rendererCreator$ = new rxjs_1.Subject();
+ _this._rendererDisposer$ = new rxjs_1.Subject();
+ _this._renderer$ = _this._rendererOperation$.pipe(operators_1.scan(function (renderer, operation) {
+ return operation(renderer);
+ }, null), operators_1.filter(function (renderer) {
+ return renderer != null;
+ }), operators_1.distinctUntilChanged(undefined, function (renderer) {
+ return renderer.frameId;
+ }));
+ _this._rendererCreator$.pipe(operators_1.map(function () {
+ return function (renderer) {
+ if (renderer != null) {
+ throw new Error("Multiple image plane states can not be created at the same time");
+ }
+ return new Component_1.ImagePlaneGLRenderer();
+ };
+ }))
+ .subscribe(_this._rendererOperation$);
+ _this._rendererDisposer$.pipe(operators_1.map(function () {
+ return function (renderer) {
+ renderer.dispose();
+ return null;
+ };
+ }))
+ .subscribe(_this._rendererOperation$);
+ return _this;
+ }
+ ImagePlaneComponent.prototype._activate = function () {
+ var _this = this;
+ this._rendererSubscription = this._renderer$.pipe(operators_1.map(function (renderer) {
+ var renderHash = {
+ name: _this._name,
+ render: {
+ frameId: renderer.frameId,
+ needsRender: renderer.needsRender,
+ render: renderer.render.bind(renderer),
+ stage: Render_1.GLRenderStage.Background,
+ },
+ };
+ renderer.clearNeedsRender();
+ return renderHash;
+ }))
+ .subscribe(this._container.glRenderer.render$);
+ this._rendererCreator$.next(null);
+ this._stateSubscription = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return function (renderer) {
+ renderer.updateFrame(frame);
+ return renderer;
+ };
+ }))
+ .subscribe(this._rendererOperation$);
+ var textureProvider$ = this._navigator.stateService.currentState$.pipe(operators_1.distinctUntilChanged(undefined, function (frame) {
+ return frame.state.currentNode.key;
+ }), operators_1.withLatestFrom(this._container.glRenderer.webGLRenderer$, this._container.renderService.size$), operators_1.map(function (_a) {
+ var frame = _a[0], renderer = _a[1], size = _a[2];
+ var state = frame.state;
+ var viewportSize = Math.max(size.width, size.height);
+ var currentNode = state.currentNode;
+ var currentTransform = state.currentTransform;
+ var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+ return new Tiles_1.TextureProvider(currentNode.key, currentTransform.basicWidth, currentTransform.basicHeight, tileSize, currentNode.image, _this._imageTileLoader, new Tiles_1.ImageTileStore(), renderer);
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ this._textureProviderSubscription = textureProvider$.subscribe(function () { });
+ this._setTextureProviderSubscription = textureProvider$.pipe(operators_1.map(function (provider) {
+ return function (renderer) {
+ renderer.setTextureProvider(provider.key, provider);
+ return renderer;
+ };
+ }))
+ .subscribe(this._rendererOperation$);
+ this._setTileSizeSubscription = this._container.renderService.size$.pipe(operators_1.switchMap(function (size) {
+ return rxjs_1.combineLatest(textureProvider$, rxjs_1.of(size)).pipe(operators_1.first());
+ }))
+ .subscribe(function (_a) {
+ var provider = _a[0], size = _a[1];
+ var viewportSize = Math.max(size.width, size.height);
+ var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+ provider.setTileSize(tileSize);
+ });
+ this._abortTextureProviderSubscription = textureProvider$.pipe(operators_1.pairwise())
+ .subscribe(function (pair) {
+ var previous = pair[0];
+ previous.abort();
+ });
+ var roiTrigger$ = rxjs_1.combineLatest(this._container.renderService.renderCameraFrame$, this._container.renderService.size$.pipe(operators_1.debounceTime(250))).pipe(operators_1.map(function (_a) {
+ var camera = _a[0], size = _a[1];
+ return [
+ camera.camera.position.clone(),
+ camera.camera.lookat.clone(),
+ camera.zoom.valueOf(),
+ size.height.valueOf(),
+ size.width.valueOf()
+ ];
+ }), operators_1.pairwise(), operators_1.skipWhile(function (pls) {
+ return pls[1][2] - pls[0][2] < 0 || pls[1][2] === 0;
+ }), operators_1.map(function (pls) {
+ var samePosition = pls[0][0].equals(pls[1][0]);
+ var sameLookat = pls[0][1].equals(pls[1][1]);
+ var sameZoom = pls[0][2] === pls[1][2];
+ var sameHeight = pls[0][3] === pls[1][3];
+ var sameWidth = pls[0][4] === pls[1][4];
+ return samePosition && sameLookat && sameZoom && sameHeight && sameWidth;
+ }), operators_1.distinctUntilChanged(), operators_1.filter(function (stalled) {
+ return stalled;
+ }), operators_1.switchMap(function (stalled) {
+ return _this._container.renderService.renderCameraFrame$.pipe(operators_1.first());
+ }), operators_1.withLatestFrom(this._container.renderService.size$, this._navigator.stateService.currentTransform$));
+ this._setRegionOfInterestSubscription = textureProvider$.pipe(operators_1.switchMap(function (provider) {
+ return roiTrigger$.pipe(operators_1.map(function (_a) {
+ var camera = _a[0], size = _a[1], transform = _a[2];
+ var basic = new ViewportCoords_1.default().viewportToBasic(0, 0, transform, camera.perspective);
+ if (basic[0] < 0 || basic[1] < 0 || basic[0] > 1 || basic[1] > 1) {
+ return undefined;
+ }
+ return [
+ _this._roiCalculator.computeRegionOfInterest(camera, size, transform),
+ provider,
+ ];
+ }), operators_1.filter(function (args) {
+ return !!args;
+ }));
+ }), operators_1.filter(function (args) {
+ return !args[1].disposed;
+ }))
+ .subscribe(function (args) {
+ var roi = args[0];
+ var provider = args[1];
+ provider.setRegionOfInterest(roi);
+ });
+ var hasTexture$ = textureProvider$.pipe(operators_1.switchMap(function (provider) {
+ return provider.hasTexture$;
+ }), operators_1.startWith(false), operators_1.publishReplay(1), operators_1.refCount());
+ this._hasTextureSubscription = hasTexture$.subscribe(function () { });
+ var nodeImage$ = this._navigator.stateService.currentState$.pipe(operators_1.filter(function (frame) {
+ return frame.state.nodesAhead === 0;
+ }), operators_1.map(function (frame) {
+ return frame.state.currentNode;
+ }), operators_1.distinctUntilChanged(undefined, function (node) {
+ return node.key;
+ }), operators_1.debounceTime(1000), operators_1.withLatestFrom(hasTexture$), operators_1.filter(function (args) {
+ return !args[1];
+ }), operators_1.map(function (args) {
+ return args[0];
+ }), operators_1.filter(function (node) {
+ return node.pano ?
+ Utils_1.Settings.maxImageSize > Utils_1.Settings.basePanoramaSize :
+ Utils_1.Settings.maxImageSize > Utils_1.Settings.baseImageSize;
+ }), operators_1.switchMap(function (node) {
+ var baseImageSize = node.pano ?
+ Utils_1.Settings.basePanoramaSize :
+ Utils_1.Settings.baseImageSize;
+ if (Math.max(node.image.width, node.image.height) > baseImageSize) {
+ return rxjs_1.empty();
+ }
+ var image$ = node
+ .cacheImage$(Utils_1.Settings.maxImageSize).pipe(operators_1.map(function (n) {
+ return [n.image, n];
+ }));
+ return image$.pipe(operators_1.takeUntil(hasTexture$.pipe(operators_1.filter(function (hasTexture) {
+ return hasTexture;
+ }))), operators_1.catchError(function (error, caught) {
+ console.error("Failed to fetch high res image (" + node.key + ")", error);
+ return rxjs_1.empty();
+ }));
+ })).pipe(operators_1.publish(), operators_1.refCount());
+ this._updateBackgroundSubscription = nodeImage$.pipe(operators_1.withLatestFrom(textureProvider$))
+ .subscribe(function (args) {
+ if (args[0][1].key !== args[1].key ||
+ args[1].disposed) {
+ return;
+ }
+ args[1].updateBackground(args[0][0]);
+ });
+ this._updateTextureImageSubscription = nodeImage$.pipe(operators_1.map(function (imn) {
+ return function (renderer) {
+ renderer.updateTextureImage(imn[0], imn[1]);
+ return renderer;
+ };
+ }))
+ .subscribe(this._rendererOperation$);
+ this._clearPeripheryPlaneSubscription = this._navigator.panService.panNodes$.pipe(operators_1.filter(function (panNodes) {
+ return panNodes.length === 0;
+ }), operators_1.map(function () {
+ return function (renderer) {
+ renderer.clearPeripheryPlanes();
+ return renderer;
+ };
+ }))
+ .subscribe(this._rendererOperation$);
+ var cachedPanNodes$ = this._navigator.panService.panNodes$.pipe(operators_1.switchMap(function (nts) {
+ return rxjs_1.from(nts).pipe(operators_1.mergeMap(function (_a) {
+ var n = _a[0], t = _a[1];
+ return rxjs_1.combineLatest(_this._navigator.graphService.cacheNode$(n.key).pipe(operators_1.catchError(function (error) {
+ console.error("Failed to cache periphery node (" + n.key + ")", error);
+ return rxjs_1.empty();
+ })), rxjs_1.of(t));
+ }));
+ }), operators_1.share());
+ this._addPeripheryPlaneSubscription = cachedPanNodes$.pipe(operators_1.map(function (_a) {
+ var n = _a[0], t = _a[1];
+ return function (renderer) {
+ renderer.addPeripheryPlane(n, t);
+ return renderer;
+ };
+ }))
+ .subscribe(this._rendererOperation$);
+ this._updatePeripheryPlaneTextureSubscription = cachedPanNodes$.pipe(operators_1.mergeMap(function (_a) {
+ var n = _a[0];
+ return Viewer_1.ImageSize.Size2048 > Math.max(n.image.width, n.image.height) ?
+ n.cacheImage$(Viewer_1.ImageSize.Size2048).pipe(operators_1.catchError(function () {
+ return rxjs_1.empty();
+ })) :
+ rxjs_1.empty();
+ }), operators_1.map(function (n) {
+ return function (renderer) {
+ renderer.updateTextureImage(n.image, n);
+ return renderer;
+ };
+ }))
+ .subscribe(this._rendererOperation$);
+ var inTransition$ = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return frame.state.alpha < 1;
+ }), operators_1.distinctUntilChanged());
+ var panTrigger$ = rxjs_1.combineLatest(this._container.mouseService.active$, this._container.touchService.active$, this._navigator.stateService.inMotion$, inTransition$).pipe(operators_1.map(function (_a) {
+ var mouseActive = _a[0], touchActive = _a[1], inMotion = _a[2], inTransition = _a[3];
+ return !(mouseActive || touchActive || inMotion || inTransition);
+ }), operators_1.filter(function (trigger) {
+ return trigger;
+ }));
+ this._moveToPeripheryNodeSubscription = this._navigator.panService.panNodes$.pipe(operators_1.switchMap(function (nts) {
+ return panTrigger$.pipe(operators_1.withLatestFrom(_this._container.renderService.renderCamera$, _this._navigator.stateService.currentNode$, _this._navigator.stateService.currentTransform$), operators_1.mergeMap(function (_a) {
+ var renderCamera = _a[1], currentNode = _a[2], currentTransform = _a[3];
+ return rxjs_1.of([
+ renderCamera,
+ currentNode,
+ currentTransform,
+ nts,
+ ]);
+ }));
+ }), operators_1.switchMap(function (_a) {
+ var camera = _a[0], cn = _a[1], ct = _a[2], nts = _a[3];
+ var direction = camera.camera.lookat.clone().sub(camera.camera.position);
+ var cd = new Spatial_1.default().viewingDirection(cn.rotation);
+ var ca = cd.angleTo(direction);
+ var closest = [ca, undefined];
+ var basic = new ViewportCoords_1.default().viewportToBasic(0, 0, ct, camera.perspective);
+ if (basic[0] >= 0 && basic[0] <= 1 && basic[1] >= 0 && basic[1] <= 1) {
+ closest[0] = Number.NEGATIVE_INFINITY;
+ }
+ for (var _i = 0, nts_1 = nts; _i < nts_1.length; _i++) {
+ var n = nts_1[_i][0];
+ var d = new Spatial_1.default().viewingDirection(n.rotation);
+ var a = d.angleTo(direction);
+ if (a < closest[0]) {
+ closest[0] = a;
+ closest[1] = n.key;
+ }
+ }
+ if (!closest[1]) {
+ return rxjs_1.empty();
+ }
+ return _this._navigator.moveToKey$(closest[1]).pipe(operators_1.catchError(function () {
+ return rxjs_1.empty();
+ }));
+ }))
+ .subscribe();
+ };
+ ImagePlaneComponent.prototype._deactivate = function () {
+ this._rendererDisposer$.next(null);
+ this._abortTextureProviderSubscription.unsubscribe();
+ this._hasTextureSubscription.unsubscribe();
+ this._rendererSubscription.unsubscribe();
+ this._setRegionOfInterestSubscription.unsubscribe();
+ this._setTextureProviderSubscription.unsubscribe();
+ this._setTileSizeSubscription.unsubscribe();
+ this._stateSubscription.unsubscribe();
+ this._textureProviderSubscription.unsubscribe();
+ this._updateBackgroundSubscription.unsubscribe();
+ this._updateTextureImageSubscription.unsubscribe();
+ this._clearPeripheryPlaneSubscription.unsubscribe();
+ this._addPeripheryPlaneSubscription.unsubscribe();
+ this._updatePeripheryPlaneTextureSubscription.unsubscribe();
+ this._moveToPeripheryNodeSubscription.unsubscribe();
+ };
+ ImagePlaneComponent.prototype._getDefaultConfiguration = function () {
+ return {};
+ };
+ ImagePlaneComponent.componentName = "imagePlane";
+ return ImagePlaneComponent;
+}(Component_1.Component));
+exports.ImagePlaneComponent = ImagePlaneComponent;
+Component_1.ComponentService.register(ImagePlaneComponent);
+exports.default = ImagePlaneComponent;
+
+},{"../../Component":275,"../../Render":281,"../../Tiles":284,"../../Utils":285,"../../Viewer":286,"../../geo/Spatial":387,"../../geo/ViewportCoords":389,"rxjs":27,"rxjs/operators":225}],306:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../Component");
+var ImagePlaneGLRenderer = /** @class */ (function () {
+ function ImagePlaneGLRenderer() {
+ this._factory = new Component_1.MeshFactory();
+ this._scene = new Component_1.MeshScene();
+ this._alpha = 0;
+ this._alphaOld = 0;
+ this._fadeOutSpeed = 0.05;
+ this._currentKey = null;
+ this._previousKey = null;
+ this._providerDisposers = {};
+ this._frameId = 0;
+ this._needsRender = false;
+ }
+ Object.defineProperty(ImagePlaneGLRenderer.prototype, "frameId", {
+ get: function () {
+ return this._frameId;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(ImagePlaneGLRenderer.prototype, "needsRender", {
+ get: function () {
+ return this._needsRender;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ImagePlaneGLRenderer.prototype.indicateNeedsRender = function () {
+ this._needsRender = true;
+ };
+ ImagePlaneGLRenderer.prototype.addPeripheryPlane = function (node, transform) {
+ var mesh = this._factory.createMesh(node, transform);
+ var planes = {};
+ planes[node.key] = mesh;
+ this._scene.addPeripheryPlanes(planes);
+ this._needsRender = true;
+ };
+ ImagePlaneGLRenderer.prototype.clearPeripheryPlanes = function () {
+ this._scene.setPeripheryPlanes({});
+ this._needsRender = true;
+ };
+ ImagePlaneGLRenderer.prototype.updateFrame = function (frame) {
+ this._updateFrameId(frame.id);
+ this._needsRender = this._updateAlpha(frame.state.alpha) || this._needsRender;
+ this._needsRender = this._updateAlphaOld(frame.state.alpha) || this._needsRender;
+ this._needsRender = this._updateImagePlanes(frame.state) || this._needsRender;
+ };
+ ImagePlaneGLRenderer.prototype.setTextureProvider = function (key, provider) {
+ var _this = this;
+ if (key !== this._currentKey) {
+ return;
+ }
+ var createdSubscription = provider.textureCreated$
+ .subscribe(function (texture) {
+ _this._updateTexture(texture);
+ });
+ var updatedSubscription = provider.textureUpdated$
+ .subscribe(function (updated) {
+ _this._needsRender = true;
+ });
+ var dispose = function () {
+ createdSubscription.unsubscribe();
+ updatedSubscription.unsubscribe();
+ provider.dispose();
+ };
+ if (key in this._providerDisposers) {
+ var disposeProvider = this._providerDisposers[key];
+ disposeProvider();
+ delete this._providerDisposers[key];
+ }
+ this._providerDisposers[key] = dispose;
+ };
+ ImagePlaneGLRenderer.prototype.updateTextureImage = function (image, node) {
+ this._needsRender = true;
+ var planes = this._extend({}, this._scene.planes, this._scene.planesOld, this._scene.planesPeriphery);
+ for (var key in planes) {
+ if (!planes.hasOwnProperty(key)) {
+ continue;
+ }
+ if (key !== node.key) {
+ continue;
+ }
+ var plane = planes[key];
+ var material = plane.material;
+ var texture = material.uniforms.projectorTex.value;
+ texture.image = image;
+ texture.needsUpdate = true;
+ }
+ };
+ ImagePlaneGLRenderer.prototype.render = function (perspectiveCamera, renderer) {
+ var planes = this._scene.planes;
+ var planesOld = this._scene.planesOld;
+ var planesPeriphery = this._scene.planesPeriphery;
+ var planeAlpha = Object.keys(planesOld).length ? 1 : this._alpha;
+ var peripheryAlpha = Object.keys(planesOld).length ? 1 : Math.floor(this._alpha);
+ for (var key in planes) {
+ if (!planes.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planes[key];
+ plane.material.uniforms.opacity.value = planeAlpha;
+ }
+ for (var key in planesOld) {
+ if (!planesOld.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planesOld[key];
+ plane.material.uniforms.opacity.value = this._alphaOld;
+ }
+ for (var key in planesPeriphery) {
+ if (!planesPeriphery.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planesPeriphery[key];
+ plane.material.uniforms.opacity.value = peripheryAlpha;
+ }
+ renderer.render(this._scene.scenePeriphery, perspectiveCamera);
+ renderer.render(this._scene.scene, perspectiveCamera);
+ renderer.render(this._scene.sceneOld, perspectiveCamera);
+ for (var key in planes) {
+ if (!planes.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planes[key];
+ plane.material.uniforms.opacity.value = this._alpha;
+ }
+ renderer.render(this._scene.scene, perspectiveCamera);
+ };
+ ImagePlaneGLRenderer.prototype.clearNeedsRender = function () {
+ this._needsRender = false;
+ };
+ ImagePlaneGLRenderer.prototype.dispose = function () {
+ this._scene.clear();
+ };
+ ImagePlaneGLRenderer.prototype._updateFrameId = function (frameId) {
+ this._frameId = frameId;
+ };
+ ImagePlaneGLRenderer.prototype._updateAlpha = function (alpha) {
+ if (alpha === this._alpha) {
+ return false;
+ }
+ this._alpha = alpha;
+ return true;
+ };
+ ImagePlaneGLRenderer.prototype._updateAlphaOld = function (alpha) {
+ if (alpha < 1 || this._alphaOld === 0) {
+ return false;
+ }
+ this._alphaOld = Math.max(0, this._alphaOld - this._fadeOutSpeed);
+ return true;
+ };
+ ImagePlaneGLRenderer.prototype._updateImagePlanes = function (state) {
+ if (state.currentNode == null || state.currentNode.key === this._currentKey) {
+ return false;
+ }
+ var previousKey = state.previousNode != null ? state.previousNode.key : null;
+ var currentKey = state.currentNode.key;
+ if (this._previousKey !== previousKey &&
+ this._previousKey !== currentKey &&
+ this._previousKey in this._providerDisposers) {
+ var disposeProvider = this._providerDisposers[this._previousKey];
+ disposeProvider();
+ delete this._providerDisposers[this._previousKey];
+ }
+ if (previousKey != null) {
+ if (previousKey !== this._currentKey && previousKey !== this._previousKey) {
+ var previousMesh = this._factory.createMesh(state.previousNode, state.previousTransform);
+ var previousPlanes = {};
+ previousPlanes[previousKey] = previousMesh;
+ this._scene.updateImagePlanes(previousPlanes);
+ }
+ this._previousKey = previousKey;
+ }
+ this._currentKey = currentKey;
+ var currentMesh = this._factory.createMesh(state.currentNode, state.currentTransform);
+ var planes = {};
+ planes[currentKey] = currentMesh;
+ this._scene.updateImagePlanes(planes);
+ this._alphaOld = 1;
+ return true;
+ };
+ ImagePlaneGLRenderer.prototype._updateTexture = function (texture) {
+ this._needsRender = true;
+ var planes = this._scene.planes;
+ for (var key in planes) {
+ if (!planes.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planes[key];
+ var material = plane.material;
+ var oldTexture = material.uniforms.projectorTex.value;
+ material.uniforms.projectorTex.value = null;
+ oldTexture.dispose();
+ material.uniforms.projectorTex.value = texture;
+ }
+ };
+ ImagePlaneGLRenderer.prototype._extend = function (dest) {
+ var sources = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ sources[_i - 1] = arguments[_i];
+ }
+ for (var _a = 0, sources_1 = sources; _a < sources_1.length; _a++) {
+ var src = sources_1[_a];
+ for (var k in src) {
+ if (!src.hasOwnProperty(k)) {
+ continue;
+ }
+ dest[k] = src[k];
+ }
+ }
+ return dest;
+ };
+ return ImagePlaneGLRenderer;
+}());
+exports.ImagePlaneGLRenderer = ImagePlaneGLRenderer;
+exports.default = ImagePlaneGLRenderer;
+
+},{"../../Component":275}],307:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var CoverState;
+(function (CoverState) {
+ CoverState[CoverState["Hidden"] = 0] = "Hidden";
+ CoverState[CoverState["Loading"] = 1] = "Loading";
+ CoverState[CoverState["Visible"] = 2] = "Visible";
+})(CoverState = exports.CoverState || (exports.CoverState = {}));
+
+},{}],308:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * Enumeration for slider mode.
+ *
+ * @enum {number}
+ * @readonly
+ *
+ * @description Modes for specifying how transitions
+ * between nodes are performed in slider mode. Only
+ * applicable when the slider component determines
+ * that transitions with motion is possilble. When it
+ * is not, the stationary mode will be applied.
+ */
+var SliderMode;
+(function (SliderMode) {
+ /**
+ * Transitions with motion.
+ *
+ * @description The slider component moves the
+ * camera between the node origins.
+ *
+ * In this mode it is not possible to zoom or pan.
+ *
+ * The slider component falls back to stationary
+ * mode when it determines that the pair of nodes
+ * does not have a strong enough relation.
+ */
+ SliderMode[SliderMode["Motion"] = 0] = "Motion";
+ /**
+ * Stationary transitions.
+ *
+ * @description The camera is stationary.
+ *
+ * In this mode it is possible to zoom and pan.
+ */
+ SliderMode[SliderMode["Stationary"] = 1] = "Stationary";
+})(SliderMode = exports.SliderMode || (exports.SliderMode = {}));
+
+},{}],309:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var ICoverConfiguration_1 = require("./ICoverConfiguration");
+exports.CoverState = ICoverConfiguration_1.CoverState;
+var ISliderConfiguration_1 = require("./ISliderConfiguration");
+exports.SliderMode = ISliderConfiguration_1.SliderMode;
+
+},{"./ICoverConfiguration":307,"./ISliderConfiguration":308}],310:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+var Edge_1 = require("../../Edge");
+/**
+ * The `KeyPlayHandler` allows the user to control the play behavior
+ * using the following key commands:
+ *
+ * `Spacebar`: Start or stop playing.
+ * `SHIFT` + `D`: Switch direction.
+ * `<`: Decrease speed.
+ * `>`: Increase speed.
+ *
+ * @example
+ * ```
+ * var keyboardComponent = viewer.getComponent("keyboard");
+ *
+ * keyboardComponent.keyPlay.disable();
+ * keyboardComponent.keyPlay.enable();
+ *
+ * var isEnabled = keyboardComponent.keyPlay.isEnabled;
+ * ```
+ */
+var KeyPlayHandler = /** @class */ (function (_super) {
+ __extends(KeyPlayHandler, _super);
+ function KeyPlayHandler() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ KeyPlayHandler.prototype._enable = function () {
+ var _this = this;
+ this._keyDownSubscription = this._container.keyboardService.keyDown$.pipe(operators_1.withLatestFrom(this._navigator.playService.playing$, this._navigator.playService.direction$, this._navigator.playService.speed$, this._navigator.stateService.currentNode$.pipe(operators_1.switchMap(function (node) {
+ return node.sequenceEdges$;
+ }))))
+ .subscribe(function (_a) {
+ var event = _a[0], playing = _a[1], direction = _a[2], speed = _a[3], status = _a[4];
+ if (event.altKey || event.ctrlKey || event.metaKey) {
+ return;
+ }
+ switch (event.key) {
+ case "D":
+ if (!event.shiftKey) {
+ return;
+ }
+ var newDirection = playing ?
+ null : direction === Edge_1.EdgeDirection.Next ?
+ Edge_1.EdgeDirection.Prev : direction === Edge_1.EdgeDirection.Prev ?
+ Edge_1.EdgeDirection.Next : null;
+ if (newDirection != null) {
+ _this._navigator.playService.setDirection(newDirection);
+ }
+ break;
+ case " ":
+ if (event.shiftKey) {
+ return;
+ }
+ if (playing) {
+ _this._navigator.playService.stop();
+ }
+ else {
+ for (var _i = 0, _b = status.edges; _i < _b.length; _i++) {
+ var edge = _b[_i];
+ if (edge.data.direction === direction) {
+ _this._navigator.playService.play();
+ }
+ }
+ }
+ break;
+ case "<":
+ _this._navigator.playService.setSpeed(speed - 0.05);
+ break;
+ case ">":
+ _this._navigator.playService.setSpeed(speed + 0.05);
+ break;
+ default:
+ return;
+ }
+ event.preventDefault();
+ });
+ };
+ KeyPlayHandler.prototype._disable = function () {
+ this._keyDownSubscription.unsubscribe();
+ };
+ KeyPlayHandler.prototype._getConfiguration = function (enable) {
+ return { keyZoom: enable };
+ };
+ return KeyPlayHandler;
+}(Component_1.HandlerBase));
+exports.KeyPlayHandler = KeyPlayHandler;
+exports.default = KeyPlayHandler;
+
+},{"../../Component":275,"../../Edge":276,"rxjs/operators":225}],311:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+var Edge_1 = require("../../Edge");
+var Error_1 = require("../../Error");
+/**
+ * The `KeySequenceNavigationHandler` allows the user to navigate through a sequence using the
+ * following key commands:
+ *
+ * `ALT` + `Up Arrow`: Navigate to next image in the sequence.
+ * `ALT` + `Down Arrow`: Navigate to previous image in sequence.
+ *
+ * @example
+ * ```
+ * var keyboardComponent = viewer.getComponent("keyboard");
+ *
+ * keyboardComponent.keySequenceNavigation.disable();
+ * keyboardComponent.keySequenceNavigation.enable();
+ *
+ * var isEnabled = keyboardComponent.keySequenceNavigation.isEnabled;
+ * ```
+ */
+var KeySequenceNavigationHandler = /** @class */ (function (_super) {
+ __extends(KeySequenceNavigationHandler, _super);
+ function KeySequenceNavigationHandler() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ KeySequenceNavigationHandler.prototype._enable = function () {
+ var _this = this;
+ var sequenceEdges$ = this._navigator.stateService.currentNode$.pipe(operators_1.switchMap(function (node) {
+ return node.sequenceEdges$;
+ }));
+ this._keyDownSubscription = this._container.keyboardService.keyDown$.pipe(operators_1.withLatestFrom(sequenceEdges$))
+ .subscribe(function (_a) {
+ var event = _a[0], edgeStatus = _a[1];
+ var direction = null;
+ switch (event.keyCode) {
+ case 38: // up
+ direction = Edge_1.EdgeDirection.Next;
+ break;
+ case 40: // down
+ direction = Edge_1.EdgeDirection.Prev;
+ break;
+ default:
+ return;
+ }
+ event.preventDefault();
+ if (!event.altKey || event.shiftKey || !edgeStatus.cached) {
+ return;
+ }
+ for (var _i = 0, _b = edgeStatus.edges; _i < _b.length; _i++) {
+ var edge = _b[_i];
+ if (edge.data.direction === direction) {
+ _this._navigator.moveToKey$(edge.to)
+ .subscribe(undefined, function (error) {
+ if (!(error instanceof Error_1.AbortMapillaryError)) {
+ console.error(error);
+ }
+ });
+ return;
+ }
+ }
+ });
+ };
+ KeySequenceNavigationHandler.prototype._disable = function () {
+ this._keyDownSubscription.unsubscribe();
+ };
+ KeySequenceNavigationHandler.prototype._getConfiguration = function (enable) {
+ return { keySequenceNavigation: enable };
+ };
+ return KeySequenceNavigationHandler;
+}(Component_1.HandlerBase));
+exports.KeySequenceNavigationHandler = KeySequenceNavigationHandler;
+exports.default = KeySequenceNavigationHandler;
+
+},{"../../Component":275,"../../Edge":276,"../../Error":277,"rxjs/operators":225}],312:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+var Edge_1 = require("../../Edge");
+var Error_1 = require("../../Error");
+/**
+ * The `KeySpatialNavigationHandler` allows the user to navigate through a sequence using the
+ * following key commands:
+ *
+ * `Up Arrow`: Step forward.
+ * `Down Arrow`: Step backward.
+ * `Left Arrow`: Step to the left.
+ * `Rigth Arrow`: Step to the right.
+ * `SHIFT` + `Down Arrow`: Turn around.
+ * `SHIFT` + `Left Arrow`: Turn to the left.
+ * `SHIFT` + `Rigth Arrow`: Turn to the right.
+ *
+ * @example
+ * ```
+ * var keyboardComponent = viewer.getComponent("keyboard");
+ *
+ * keyboardComponent.keySpatialNavigation.disable();
+ * keyboardComponent.keySpatialNavigation.enable();
+ *
+ * var isEnabled = keyboardComponent.keySpatialNavigation.isEnabled;
+ * ```
+ */
+var KeySpatialNavigationHandler = /** @class */ (function (_super) {
+ __extends(KeySpatialNavigationHandler, _super);
+ /** @ignore */
+ function KeySpatialNavigationHandler(component, container, navigator, spatial) {
+ var _this = _super.call(this, component, container, navigator) || this;
+ _this._spatial = spatial;
+ return _this;
+ }
+ KeySpatialNavigationHandler.prototype._enable = function () {
+ var _this = this;
+ var spatialEdges$ = this._navigator.stateService.currentNode$.pipe(operators_1.switchMap(function (node) {
+ return node.spatialEdges$;
+ }));
+ this._keyDownSubscription = this._container.keyboardService.keyDown$.pipe(operators_1.withLatestFrom(spatialEdges$, this._navigator.stateService.currentState$))
+ .subscribe(function (_a) {
+ var event = _a[0], edgeStatus = _a[1], frame = _a[2];
+ var pano = frame.state.currentNode.pano;
+ var direction = null;
+ switch (event.keyCode) {
+ case 37: // left
+ direction = event.shiftKey && !pano ? Edge_1.EdgeDirection.TurnLeft : Edge_1.EdgeDirection.StepLeft;
+ break;
+ case 38: // up
+ direction = event.shiftKey && !pano ? Edge_1.EdgeDirection.Pano : Edge_1.EdgeDirection.StepForward;
+ break;
+ case 39: // right
+ direction = event.shiftKey && !pano ? Edge_1.EdgeDirection.TurnRight : Edge_1.EdgeDirection.StepRight;
+ break;
+ case 40: // down
+ direction = event.shiftKey && !pano ? Edge_1.EdgeDirection.TurnU : Edge_1.EdgeDirection.StepBackward;
+ break;
+ default:
+ return;
+ }
+ event.preventDefault();
+ if (event.altKey || !edgeStatus.cached ||
+ (event.shiftKey && pano)) {
+ return;
+ }
+ if (!pano) {
+ _this._moveDir(direction, edgeStatus);
+ }
+ else {
+ var shifts = {};
+ shifts[Edge_1.EdgeDirection.StepBackward] = Math.PI;
+ shifts[Edge_1.EdgeDirection.StepForward] = 0;
+ shifts[Edge_1.EdgeDirection.StepLeft] = Math.PI / 2;
+ shifts[Edge_1.EdgeDirection.StepRight] = -Math.PI / 2;
+ var phi = _this._rotationFromCamera(frame.state.camera).phi;
+ var navigationAngle = _this._spatial.wrapAngle(phi + shifts[direction]);
+ var threshold = Math.PI / 4;
+ var edges = edgeStatus.edges.filter(function (e) {
+ return e.data.direction === Edge_1.EdgeDirection.Pano || e.data.direction === direction;
+ });
+ var smallestAngle = Number.MAX_VALUE;
+ var toKey = null;
+ for (var _i = 0, edges_1 = edges; _i < edges_1.length; _i++) {
+ var edge = edges_1[_i];
+ var angle = Math.abs(_this._spatial.wrapAngle(edge.data.worldMotionAzimuth - navigationAngle));
+ if (angle < Math.min(smallestAngle, threshold)) {
+ smallestAngle = angle;
+ toKey = edge.to;
+ }
+ }
+ if (toKey == null) {
+ return;
+ }
+ _this._moveToKey(toKey);
+ }
+ });
+ };
+ KeySpatialNavigationHandler.prototype._disable = function () {
+ this._keyDownSubscription.unsubscribe();
+ };
+ KeySpatialNavigationHandler.prototype._getConfiguration = function (enable) {
+ return { keySpatialNavigation: enable };
+ };
+ KeySpatialNavigationHandler.prototype._moveDir = function (direction, edgeStatus) {
+ for (var _i = 0, _a = edgeStatus.edges; _i < _a.length; _i++) {
+ var edge = _a[_i];
+ if (edge.data.direction === direction) {
+ this._moveToKey(edge.to);
+ return;
+ }
+ }
+ };
+ KeySpatialNavigationHandler.prototype._moveToKey = function (key) {
+ this._navigator.moveToKey$(key)
+ .subscribe(undefined, function (error) {
+ if (!(error instanceof Error_1.AbortMapillaryError)) {
+ console.error(error);
+ }
+ });
+ };
+ KeySpatialNavigationHandler.prototype._rotationFromCamera = function (camera) {
+ var direction = camera.lookat.clone().sub(camera.position);
+ var upProjection = direction.clone().dot(camera.up);
+ var planeProjection = direction.clone().sub(camera.up.clone().multiplyScalar(upProjection));
+ var phi = Math.atan2(planeProjection.y, planeProjection.x);
+ var theta = Math.PI / 2 - this._spatial.angleToPlane(direction.toArray(), [0, 0, 1]);
+ return { phi: phi, theta: theta };
+ };
+ return KeySpatialNavigationHandler;
+}(Component_1.HandlerBase));
+exports.KeySpatialNavigationHandler = KeySpatialNavigationHandler;
+exports.default = KeySpatialNavigationHandler;
+
+},{"../../Component":275,"../../Edge":276,"../../Error":277,"rxjs/operators":225}],313:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+/**
+ * The `KeyZoomHandler` allows the user to zoom in and out using the
+ * following key commands:
+ *
+ * `+`: Zoom in.
+ * `-`: Zoom out.
+ *
+ * @example
+ * ```
+ * var keyboardComponent = viewer.getComponent("keyboard");
+ *
+ * keyboardComponent.keyZoom.disable();
+ * keyboardComponent.keyZoom.enable();
+ *
+ * var isEnabled = keyboardComponent.keyZoom.isEnabled;
+ * ```
+ */
+var KeyZoomHandler = /** @class */ (function (_super) {
+ __extends(KeyZoomHandler, _super);
+ /** @ignore */
+ function KeyZoomHandler(component, container, navigator, viewportCoords) {
+ var _this = _super.call(this, component, container, navigator) || this;
+ _this._viewportCoords = viewportCoords;
+ return _this;
+ }
+ KeyZoomHandler.prototype._enable = function () {
+ var _this = this;
+ this._keyDownSubscription = this._container.keyboardService.keyDown$.pipe(operators_1.withLatestFrom(this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$))
+ .subscribe(function (_a) {
+ var event = _a[0], render = _a[1], transform = _a[2];
+ if (event.altKey || event.shiftKey || event.ctrlKey || event.metaKey) {
+ return;
+ }
+ var delta = 0;
+ switch (event.key) {
+ case "+":
+ delta = 1;
+ break;
+ case "-":
+ delta = -1;
+ break;
+ default:
+ return;
+ }
+ event.preventDefault();
+ var unprojected = _this._viewportCoords.unprojectFromViewport(0, 0, render.perspective);
+ var reference = transform.projectBasic(unprojected.toArray());
+ _this._navigator.stateService.zoomIn(delta, reference);
+ });
+ };
+ KeyZoomHandler.prototype._disable = function () {
+ this._keyDownSubscription.unsubscribe();
+ };
+ KeyZoomHandler.prototype._getConfiguration = function (enable) {
+ return { keyZoom: enable };
+ };
+ return KeyZoomHandler;
+}(Component_1.HandlerBase));
+exports.KeyZoomHandler = KeyZoomHandler;
+exports.default = KeyZoomHandler;
+
+},{"../../Component":275,"rxjs/operators":225}],314:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../Component");
+var Geo_1 = require("../../Geo");
+/**
+ * @class KeyboardComponent
+ *
+ * @classdesc Component for keyboard event handling.
+ *
+ * To retrive and use the keyboard component
+ *
+ * @example
+ * ```
+ * var viewer = new Mapillary.Viewer(
+ * "<element-id>",
+ * "<client-id>",
+ * "<my key>");
+ *
+ * var keyboardComponent = viewer.getComponent("keyboard");
+ * ```
+ */
+var KeyboardComponent = /** @class */ (function (_super) {
+ __extends(KeyboardComponent, _super);
+ /** @ignore */
+ function KeyboardComponent(name, container, navigator) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._keyPlayHandler = new Component_1.KeyPlayHandler(_this, container, navigator);
+ _this._keySequenceNavigationHandler = new Component_1.KeySequenceNavigationHandler(_this, container, navigator);
+ _this._keySpatialNavigationHandler = new Component_1.KeySpatialNavigationHandler(_this, container, navigator, new Geo_1.Spatial());
+ _this._keyZoomHandler = new Component_1.KeyZoomHandler(_this, container, navigator, new Geo_1.ViewportCoords());
+ return _this;
+ }
+ Object.defineProperty(KeyboardComponent.prototype, "keyPlay", {
+ /**
+ * Get key play.
+ *
+ * @returns {KeyPlayHandler} The key play handler.
+ */
+ get: function () {
+ return this._keyPlayHandler;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(KeyboardComponent.prototype, "keySequenceNavigation", {
+ /**
+ * Get key sequence navigation.
+ *
+ * @returns {KeySequenceNavigationHandler} The key sequence navigation handler.
+ */
+ get: function () {
+ return this._keySequenceNavigationHandler;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(KeyboardComponent.prototype, "keySpatialNavigation", {
+ /**
+ * Get spatial.
+ *
+ * @returns {KeySpatialNavigationHandler} The spatial handler.
+ */
+ get: function () {
+ return this._keySpatialNavigationHandler;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(KeyboardComponent.prototype, "keyZoom", {
+ /**
+ * Get key zoom.
+ *
+ * @returns {KeyZoomHandler} The key zoom handler.
+ */
+ get: function () {
+ return this._keyZoomHandler;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ KeyboardComponent.prototype._activate = function () {
+ var _this = this;
+ this._configurationSubscription = this._configuration$
+ .subscribe(function (configuration) {
+ if (configuration.keyPlay) {
+ _this._keyPlayHandler.enable();
+ }
+ else {
+ _this._keyPlayHandler.disable();
+ }
+ if (configuration.keySequenceNavigation) {
+ _this._keySequenceNavigationHandler.enable();
+ }
+ else {
+ _this._keySequenceNavigationHandler.disable();
+ }
+ if (configuration.keySpatialNavigation) {
+ _this._keySpatialNavigationHandler.enable();
+ }
+ else {
+ _this._keySpatialNavigationHandler.disable();
+ }
+ if (configuration.keyZoom) {
+ _this._keyZoomHandler.enable();
+ }
+ else {
+ _this._keyZoomHandler.disable();
+ }
+ });
+ };
+ KeyboardComponent.prototype._deactivate = function () {
+ this._configurationSubscription.unsubscribe();
+ this._keyPlayHandler.disable();
+ this._keySequenceNavigationHandler.disable();
+ this._keySpatialNavigationHandler.disable();
+ this._keyZoomHandler.disable();
+ };
+ KeyboardComponent.prototype._getDefaultConfiguration = function () {
+ return { keyPlay: true, keySequenceNavigation: true, keySpatialNavigation: true, keyZoom: true };
+ };
+ KeyboardComponent.componentName = "keyboard";
+ return KeyboardComponent;
+}(Component_1.Component));
+exports.KeyboardComponent = KeyboardComponent;
+Component_1.ComponentService.register(KeyboardComponent);
+exports.default = KeyboardComponent;
+
+},{"../../Component":275,"../../Geo":278}],315:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var MarkerComponent_1 = require("./MarkerComponent");
+exports.MarkerComponent = MarkerComponent_1.MarkerComponent;
+var SimpleMarker_1 = require("./marker/SimpleMarker");
+exports.SimpleMarker = SimpleMarker_1.SimpleMarker;
+var CircleMarker_1 = require("./marker/CircleMarker");
+exports.CircleMarker = CircleMarker_1.CircleMarker;
+
+},{"./MarkerComponent":316,"./marker/CircleMarker":319,"./marker/SimpleMarker":321}],316:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var THREE = require("three");
+var when = require("when");
+var Component_1 = require("../../Component");
+var Render_1 = require("../../Render");
+var Graph_1 = require("../../Graph");
+var Geo_1 = require("../../Geo");
+/**
+ * @class MarkerComponent
+ *
+ * @classdesc Component for showing and editing 3D marker objects.
+ *
+ * The `add` method is used for adding new markers or replacing
+ * markers already in the set.
+ *
+ * If a marker already in the set has the same
+ * id as one of the markers added, the old marker will be removed and
+ * the added marker will take its place.
+ *
+ * It is not possible to update markers in the set by updating any properties
+ * directly on the marker object. Markers need to be replaced by
+ * re-adding them for updates to geographic position or configuration
+ * to be reflected.
+ *
+ * Markers added to the marker component can be either interactive
+ * or non-interactive. Different marker types define their behavior.
+ * Markers with interaction support can be configured with options
+ * to respond to dragging inside the viewer and be detected when
+ * retrieving markers from pixel points with the `getMarkerIdAt` method.
+ *
+ * To retrive and use the marker component
+ *
+ * @example
+ * ```
+ * var viewer = new Mapillary.Viewer(
+ * "<element-id>",
+ * "<client-id>",
+ * "<my key>",
+ * { component: { marker: true } });
+ *
+ * var markerComponent = viewer.getComponent("marker");
+ * ```
+ */
+var MarkerComponent = /** @class */ (function (_super) {
+ __extends(MarkerComponent, _super);
+ /** @ignore */
+ function MarkerComponent(name, container, navigator) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._relativeGroundAltitude = -2;
+ _this._geoCoords = new Geo_1.GeoCoords();
+ _this._graphCalculator = new Graph_1.GraphCalculator();
+ _this._markerScene = new Component_1.MarkerScene();
+ _this._markerSet = new Component_1.MarkerSet();
+ _this._viewportCoords = new Geo_1.ViewportCoords();
+ return _this;
+ }
+ /**
+ * Add markers to the marker set or replace markers in the marker set.
+ *
+ * @description If a marker already in the set has the same
+ * id as one of the markers added, the old marker will be removed
+ * the added marker will take its place.
+ *
+ * Any marker inside the visible bounding bbox
+ * will be initialized and placed in the viewer.
+ *
+ * @param {Array<Marker>} markers - Markers to add.
+ *
+ * @example ```markerComponent.add([marker1, marker2]);```
+ */
+ MarkerComponent.prototype.add = function (markers) {
+ this._markerSet.add(markers);
+ };
+ /**
+ * Returns the marker in the marker set with the specified id, or
+ * undefined if the id matches no marker.
+ *
+ * @param {string} markerId - Id of the marker.
+ *
+ * @example ```var marker = markerComponent.get("markerId");```
+ *
+ */
+ MarkerComponent.prototype.get = function (markerId) {
+ return this._markerSet.get(markerId);
+ };
+ /**
+ * Returns an array of all markers.
+ *
+ * @example ```var markers = markerComponent.getAll();```
+ */
+ MarkerComponent.prototype.getAll = function () {
+ return this._markerSet.getAll();
+ };
+ /**
+ * Returns the id of the interactive marker closest to the current camera
+ * position at the specified point.
+ *
+ * @description Notice that the pixelPoint argument requires x, y
+ * coordinates from pixel space.
+ *
+ * With this function, you can use the coordinates provided by mouse
+ * events to get information out of the marker component.
+ *
+ * If no interactive geometry of an interactive marker exist at the pixel
+ * point, `null` will be returned.
+ *
+ * @param {Array<number>} pixelPoint - Pixel coordinates on the viewer element.
+ * @returns {string} Id of the interactive marker closest to the camera. If no
+ * interactive marker exist at the pixel point, `null` will be returned.
+ *
+ * @example
+ * ```
+ * markerComponent.getMarkerIdAt([100, 100])
+ * .then((markerId) => { console.log(markerId); });
+ * ```
+ */
+ MarkerComponent.prototype.getMarkerIdAt = function (pixelPoint) {
+ var _this = this;
+ return when.promise(function (resolve, reject) {
+ _this._container.renderService.renderCamera$.pipe(operators_1.first(), operators_1.map(function (render) {
+ var viewport = _this._viewportCoords
+ .canvasToViewport(pixelPoint[0], pixelPoint[1], _this._container.element);
+ var id = _this._markerScene.intersectObjects(viewport, render.perspective);
+ return id;
+ }))
+ .subscribe(function (id) {
+ resolve(id);
+ }, function (error) {
+ reject(error);
+ });
+ });
+ };
+ /**
+ * Check if a marker exist in the marker set.
+ *
+ * @param {string} markerId - Id of the marker.
+ *
+ * @example ```var markerExists = markerComponent.has("markerId");```
+ */
+ MarkerComponent.prototype.has = function (markerId) {
+ return this._markerSet.has(markerId);
+ };
+ /**
+ * Remove markers with the specified ids from the marker set.
+ *
+ * @param {Array<string>} markerIds - Ids for markers to remove.
+ *
+ * @example ```markerComponent.remove(["id-1", "id-2"]);```
+ */
+ MarkerComponent.prototype.remove = function (markerIds) {
+ this._markerSet.remove(markerIds);
+ };
+ /**
+ * Remove all markers from the marker set.
+ *
+ * @example ```markerComponent.removeAll();```
+ */
+ MarkerComponent.prototype.removeAll = function () {
+ this._markerSet.removeAll();
+ };
+ MarkerComponent.prototype._activate = function () {
+ var _this = this;
+ var groundAltitude$ = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return frame.state.camera.position.z + _this._relativeGroundAltitude;
+ }), operators_1.distinctUntilChanged(function (a1, a2) {
+ return Math.abs(a1 - a2) < 0.01;
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ var geoInitiated$ = rxjs_1.combineLatest(groundAltitude$, this._navigator.stateService.reference$).pipe(operators_1.first(), operators_1.map(function () { }), operators_1.publishReplay(1), operators_1.refCount());
+ var clampedConfiguration$ = this._configuration$.pipe(operators_1.map(function (configuration) {
+ return { visibleBBoxSize: Math.max(1, Math.min(200, configuration.visibleBBoxSize)) };
+ }));
+ var currentlatLon$ = this._navigator.stateService.currentNode$.pipe(operators_1.map(function (node) { return node.latLon; }), operators_1.publishReplay(1), operators_1.refCount());
+ var visibleBBox$ = rxjs_1.combineLatest(clampedConfiguration$, currentlatLon$).pipe(operators_1.map(function (_a) {
+ var configuration = _a[0], latLon = _a[1];
+ return _this._graphCalculator
+ .boundingBoxCorners(latLon, configuration.visibleBBoxSize / 2);
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ var visibleMarkers$ = rxjs_1.combineLatest(rxjs_1.concat(rxjs_1.of(this._markerSet), this._markerSet.changed$), visibleBBox$).pipe(operators_1.map(function (_a) {
+ var set = _a[0], bbox = _a[1];
+ return set.search(bbox);
+ }));
+ this._setChangedSubscription = geoInitiated$.pipe(operators_1.switchMap(function () {
+ return visibleMarkers$.pipe(operators_1.withLatestFrom(_this._navigator.stateService.reference$, groundAltitude$));
+ }))
+ .subscribe(function (_a) {
+ var markers = _a[0], reference = _a[1], alt = _a[2];
+ var geoCoords = _this._geoCoords;
+ var markerScene = _this._markerScene;
+ var sceneMarkers = markerScene.markers;
+ var markersToRemove = Object.assign({}, sceneMarkers);
+ for (var _i = 0, markers_1 = markers; _i < markers_1.length; _i++) {
+ var marker = markers_1[_i];
+ if (marker.id in sceneMarkers) {
+ delete markersToRemove[marker.id];
+ }
+ else {
+ var point3d = geoCoords
+ .geodeticToEnu(marker.latLon.lat, marker.latLon.lon, reference.alt + alt, reference.lat, reference.lon, reference.alt);
+ markerScene.add(marker, point3d);
+ }
+ }
+ for (var id in markersToRemove) {
+ if (!markersToRemove.hasOwnProperty(id)) {
+ continue;
+ }
+ markerScene.remove(id);
+ }
+ });
+ this._markersUpdatedSubscription = geoInitiated$.pipe(operators_1.switchMap(function () {
+ return _this._markerSet.updated$.pipe(operators_1.withLatestFrom(visibleBBox$, _this._navigator.stateService.reference$, groundAltitude$));
+ }))
+ .subscribe(function (_a) {
+ var markers = _a[0], _b = _a[1], sw = _b[0], ne = _b[1], reference = _a[2], alt = _a[3];
+ var geoCoords = _this._geoCoords;
+ var markerScene = _this._markerScene;
+ for (var _i = 0, markers_2 = markers; _i < markers_2.length; _i++) {
+ var marker = markers_2[_i];
+ var exists = markerScene.has(marker.id);
+ var visible = marker.latLon.lat > sw.lat &&
+ marker.latLon.lat < ne.lat &&
+ marker.latLon.lon > sw.lon &&
+ marker.latLon.lon < ne.lon;
+ if (visible) {
+ var point3d = geoCoords
+ .geodeticToEnu(marker.latLon.lat, marker.latLon.lon, reference.alt + alt, reference.lat, reference.lon, reference.alt);
+ markerScene.add(marker, point3d);
+ }
+ else if (!visible && exists) {
+ markerScene.remove(marker.id);
+ }
+ }
+ });
+ this._referenceSubscription = this._navigator.stateService.reference$.pipe(operators_1.skip(1), operators_1.withLatestFrom(groundAltitude$))
+ .subscribe(function (_a) {
+ var reference = _a[0], alt = _a[1];
+ var geoCoords = _this._geoCoords;
+ var markerScene = _this._markerScene;
+ for (var _i = 0, _b = markerScene.getAll(); _i < _b.length; _i++) {
+ var marker = _b[_i];
+ var point3d = geoCoords
+ .geodeticToEnu(marker.latLon.lat, marker.latLon.lon, reference.alt + alt, reference.lat, reference.lon, reference.alt);
+ markerScene.update(marker.id, point3d);
+ }
+ });
+ this._adjustHeightSubscription = groundAltitude$.pipe(operators_1.skip(1), operators_1.withLatestFrom(this._navigator.stateService.reference$, currentlatLon$))
+ .subscribe(function (_a) {
+ var alt = _a[0], reference = _a[1], latLon = _a[2];
+ var geoCoords = _this._geoCoords;
+ var markerScene = _this._markerScene;
+ var position = geoCoords
+ .geodeticToEnu(latLon.lat, latLon.lon, reference.alt + alt, reference.lat, reference.lon, reference.alt);
+ for (var _i = 0, _b = markerScene.getAll(); _i < _b.length; _i++) {
+ var marker = _b[_i];
+ var point3d = geoCoords
+ .geodeticToEnu(marker.latLon.lat, marker.latLon.lon, reference.alt + alt, reference.lat, reference.lon, reference.alt);
+ var distanceX = point3d[0] - position[0];
+ var distanceY = point3d[1] - position[1];
+ var groundDistance = Math.sqrt(distanceX * distanceX + distanceY * distanceY);
+ if (groundDistance > 50) {
+ continue;
+ }
+ markerScene.lerpAltitude(marker.id, alt, Math.min(1, Math.max(0, 1.2 - 1.2 * groundDistance / 50)));
+ }
+ });
+ this._renderSubscription = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ var scene = _this._markerScene;
+ return {
+ name: _this._name,
+ render: {
+ frameId: frame.id,
+ needsRender: scene.needsRender,
+ render: scene.render.bind(scene),
+ stage: Render_1.GLRenderStage.Foreground,
+ },
+ };
+ }))
+ .subscribe(this._container.glRenderer.render$);
+ var hoveredMarkerId$ = rxjs_1.combineLatest(this._container.renderService.renderCamera$, this._container.mouseService.mouseMove$).pipe(operators_1.map(function (_a) {
+ var render = _a[0], event = _a[1];
+ var element = _this._container.element;
+ var _b = _this._viewportCoords.canvasPosition(event, element), canvasX = _b[0], canvasY = _b[1];
+ var viewport = _this._viewportCoords.canvasToViewport(canvasX, canvasY, element);
+ var markerId = _this._markerScene.intersectObjects(viewport, render.perspective);
+ return markerId;
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ var draggingStarted$ = this._container.mouseService
+ .filtered$(this._name, this._container.mouseService.mouseDragStart$).pipe(operators_1.map(function (event) {
+ return true;
+ }));
+ var draggingStopped$ = this._container.mouseService
+ .filtered$(this._name, this._container.mouseService.mouseDragEnd$).pipe(operators_1.map(function (event) {
+ return false;
+ }));
+ var filteredDragging$ = rxjs_1.merge(draggingStarted$, draggingStopped$).pipe(operators_1.startWith(false));
+ this._dragEventSubscription = rxjs_1.merge(draggingStarted$.pipe(operators_1.withLatestFrom(hoveredMarkerId$)), rxjs_1.combineLatest(draggingStopped$, rxjs_1.of(null))).pipe(operators_1.startWith([false, null]), operators_1.pairwise())
+ .subscribe(function (_a) {
+ var previous = _a[0], current = _a[1];
+ var dragging = current[0];
+ var eventType = dragging ? MarkerComponent.dragstart : MarkerComponent.dragend;
+ var id = dragging ? current[1] : previous[1];
+ var marker = _this._markerScene.get(id);
+ var markerEvent = { marker: marker, target: _this, type: eventType };
+ _this.fire(eventType, markerEvent);
+ });
+ var mouseDown$ = rxjs_1.merge(this._container.mouseService.mouseDown$.pipe(operators_1.map(function (event) { return true; })), this._container.mouseService.documentMouseUp$.pipe(operators_1.map(function (event) { return false; }))).pipe(operators_1.startWith(false));
+ this._mouseClaimSubscription = rxjs_1.combineLatest(this._container.mouseService.active$, hoveredMarkerId$.pipe(operators_1.distinctUntilChanged()), mouseDown$, filteredDragging$).pipe(operators_1.map(function (_a) {
+ var active = _a[0], markerId = _a[1], mouseDown = _a[2], filteredDragging = _a[3];
+ return (!active && markerId != null && mouseDown) || filteredDragging;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (claim) {
+ if (claim) {
+ _this._container.mouseService.claimMouse(_this._name, 1);
+ _this._container.mouseService.claimWheel(_this._name, 1);
+ }
+ else {
+ _this._container.mouseService.unclaimMouse(_this._name);
+ _this._container.mouseService.unclaimWheel(_this._name);
+ }
+ });
+ var offset$ = this._container.mouseService
+ .filtered$(this._name, this._container.mouseService.mouseDragStart$).pipe(operators_1.withLatestFrom(hoveredMarkerId$, this._container.renderService.renderCamera$), operators_1.map(function (_a) {
+ var e = _a[0], id = _a[1], r = _a[2];
+ var marker = _this._markerScene.get(id);
+ var element = _this._container.element;
+ var _b = _this._viewportCoords.projectToCanvas(marker.geometry.position.toArray(), element, r.perspective), groundCanvasX = _b[0], groundCanvasY = _b[1];
+ var _c = _this._viewportCoords.canvasPosition(e, element), canvasX = _c[0], canvasY = _c[1];
+ var offset = [canvasX - groundCanvasX, canvasY - groundCanvasY];
+ return [marker, offset, r];
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ this._updateMarkerSubscription = this._container.mouseService
+ .filtered$(this._name, this._container.mouseService.mouseDrag$).pipe(operators_1.withLatestFrom(offset$, this._navigator.stateService.reference$, clampedConfiguration$))
+ .subscribe(function (_a) {
+ var event = _a[0], _b = _a[1], marker = _b[0], offset = _b[1], render = _b[2], reference = _a[2], configuration = _a[3];
+ if (!_this._markerScene.has(marker.id)) {
+ return;
+ }
+ var element = _this._container.element;
+ var _c = _this._viewportCoords.canvasPosition(event, element), canvasX = _c[0], canvasY = _c[1];
+ var groundX = canvasX - offset[0];
+ var groundY = canvasY - offset[1];
+ var _d = _this._viewportCoords
+ .canvasToViewport(groundX, groundY, element), viewportX = _d[0], viewportY = _d[1];
+ var direction = new THREE.Vector3(viewportX, viewportY, 1)
+ .unproject(render.perspective)
+ .sub(render.perspective.position)
+ .normalize();
+ var distance = Math.min(_this._relativeGroundAltitude / direction.z, configuration.visibleBBoxSize / 2 - 0.1);
+ if (distance < 0) {
+ return;
+ }
+ var intersection = direction
+ .clone()
+ .multiplyScalar(distance)
+ .add(render.perspective.position);
+ intersection.z = render.perspective.position.z + _this._relativeGroundAltitude;
+ var _e = _this._geoCoords
+ .enuToGeodetic(intersection.x, intersection.y, intersection.z, reference.lat, reference.lon, reference.alt), lat = _e[0], lon = _e[1];
+ _this._markerScene.update(marker.id, intersection.toArray(), { lat: lat, lon: lon });
+ _this._markerSet.update(marker);
+ var markerEvent = { marker: marker, target: _this, type: MarkerComponent.changed };
+ _this.fire(MarkerComponent.changed, markerEvent);
+ });
+ };
+ MarkerComponent.prototype._deactivate = function () {
+ this._adjustHeightSubscription.unsubscribe();
+ this._dragEventSubscription.unsubscribe();
+ this._markersUpdatedSubscription.unsubscribe();
+ this._mouseClaimSubscription.unsubscribe();
+ this._referenceSubscription.unsubscribe();
+ this._renderSubscription.unsubscribe();
+ this._setChangedSubscription.unsubscribe();
+ this._updateMarkerSubscription.unsubscribe();
+ this._markerScene.clear();
+ };
+ MarkerComponent.prototype._getDefaultConfiguration = function () {
+ return { visibleBBoxSize: 100 };
+ };
+ MarkerComponent.componentName = "marker";
+ /**
+ * Fired when the position of a marker is changed.
+ * @event
+ * @type {IMarkerEvent} markerEvent - Marker event data.
+ * @example
+ * ```
+ * markerComponent.on("changed", function(e) {
+ * console.log(e.marker.id, e.marker.latLon);
+ * });
+ * ```
+ */
+ MarkerComponent.changed = "changed";
+ /**
+ * Fired when a marker drag interaction starts.
+ * @event
+ * @type {IMarkerEvent} markerEvent - Marker event data.
+ * @example
+ * ```
+ * markerComponent.on("dragstart", function(e) {
+ * console.log(e.marker.id, e.marker.latLon);
+ * });
+ * ```
+ */
+ MarkerComponent.dragstart = "dragstart";
+ /**
+ * Fired when a marker drag interaction ends.
+ * @event
+ * @type {IMarkerEvent} markerEvent - Marker event data.
+ * @example
+ * ```
+ * markerComponent.on("dragend", function(e) {
+ * console.log(e.marker.id, e.marker.latLon);
+ * });
+ * ```
+ */
+ MarkerComponent.dragend = "dragend";
+ return MarkerComponent;
+}(Component_1.Component));
+exports.MarkerComponent = MarkerComponent;
+Component_1.ComponentService.register(MarkerComponent);
+exports.default = MarkerComponent;
+
+
+},{"../../Component":275,"../../Geo":278,"../../Graph":279,"../../Render":281,"rxjs":27,"rxjs/operators":225,"three":226,"when":272}],317:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var MarkerScene = /** @class */ (function () {
+ function MarkerScene(scene, raycaster) {
+ this._needsRender = false;
+ this._interactiveObjects = [];
+ this._markers = {};
+ this._objectMarkers = {};
+ this._raycaster = !!raycaster ? raycaster : new THREE.Raycaster();
+ this._scene = !!scene ? scene : new THREE.Scene();
+ }
+ Object.defineProperty(MarkerScene.prototype, "markers", {
+ get: function () {
+ return this._markers;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(MarkerScene.prototype, "needsRender", {
+ get: function () {
+ return this._needsRender;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ MarkerScene.prototype.add = function (marker, position) {
+ if (marker.id in this._markers) {
+ this._dispose(marker.id);
+ }
+ marker.createGeometry(position);
+ this._scene.add(marker.geometry);
+ this._markers[marker.id] = marker;
+ for (var _i = 0, _a = marker.getInteractiveObjects(); _i < _a.length; _i++) {
+ var interactiveObject = _a[_i];
+ this._interactiveObjects.push(interactiveObject);
+ this._objectMarkers[interactiveObject.uuid] = marker.id;
+ }
+ this._needsRender = true;
+ };
+ MarkerScene.prototype.clear = function () {
+ for (var id in this._markers) {
+ if (!this._markers.hasOwnProperty) {
+ continue;
+ }
+ this._dispose(id);
+ }
+ this._needsRender = true;
+ };
+ MarkerScene.prototype.get = function (id) {
+ return this._markers[id];
+ };
+ MarkerScene.prototype.getAll = function () {
+ var _this = this;
+ return Object
+ .keys(this._markers)
+ .map(function (id) { return _this._markers[id]; });
+ };
+ MarkerScene.prototype.has = function (id) {
+ return id in this._markers;
+ };
+ MarkerScene.prototype.intersectObjects = function (_a, camera) {
+ var viewportX = _a[0], viewportY = _a[1];
+ this._raycaster.setFromCamera(new THREE.Vector2(viewportX, viewportY), camera);
+ var intersects = this._raycaster.intersectObjects(this._interactiveObjects);
+ for (var _i = 0, intersects_1 = intersects; _i < intersects_1.length; _i++) {
+ var intersect = intersects_1[_i];
+ if (intersect.object.uuid in this._objectMarkers) {
+ return this._objectMarkers[intersect.object.uuid];
+ }
+ }
+ return null;
+ };
+ MarkerScene.prototype.lerpAltitude = function (id, alt, alpha) {
+ if (!(id in this._markers)) {
+ return;
+ }
+ this._markers[id].lerpAltitude(alt, alpha);
+ this._needsRender = true;
+ };
+ MarkerScene.prototype.remove = function (id) {
+ if (!(id in this._markers)) {
+ return;
+ }
+ this._dispose(id);
+ this._needsRender = true;
+ };
+ MarkerScene.prototype.render = function (perspectiveCamera, renderer) {
+ renderer.render(this._scene, perspectiveCamera);
+ this._needsRender = false;
+ };
+ MarkerScene.prototype.update = function (id, position, latLon) {
+ if (!(id in this._markers)) {
+ return;
+ }
+ var marker = this._markers[id];
+ marker.updatePosition(position, latLon);
+ this._needsRender = true;
+ };
+ MarkerScene.prototype._dispose = function (id) {
+ var marker = this._markers[id];
+ this._scene.remove(marker.geometry);
+ for (var _i = 0, _a = marker.getInteractiveObjects(); _i < _a.length; _i++) {
+ var interactiveObject = _a[_i];
+ var index = this._interactiveObjects.indexOf(interactiveObject);
+ if (index !== -1) {
+ this._interactiveObjects.splice(index, 1);
+ }
+ else {
+ console.warn("Object does not exist (" + interactiveObject.id + ") for " + id);
+ }
+ delete this._objectMarkers[interactiveObject.uuid];
+ }
+ marker.disposeGeometry();
+ delete this._markers[id];
+ };
+ return MarkerScene;
+}());
+exports.MarkerScene = MarkerScene;
+exports.default = MarkerScene;
+
+},{"three":226}],318:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var rbush = require("rbush");
+var rxjs_1 = require("rxjs");
+var MarkerSet = /** @class */ (function () {
+ function MarkerSet() {
+ this._hash = {};
+ this._index = rbush(16, [".lon", ".lat", ".lon", ".lat"]);
+ this._indexChanged$ = new rxjs_1.Subject();
+ this._updated$ = new rxjs_1.Subject();
+ }
+ Object.defineProperty(MarkerSet.prototype, "changed$", {
+ get: function () {
+ return this._indexChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(MarkerSet.prototype, "updated$", {
+ get: function () {
+ return this._updated$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ MarkerSet.prototype.add = function (markers) {
+ var updated = [];
+ var hash = this._hash;
+ var index = this._index;
+ for (var _i = 0, markers_1 = markers; _i < markers_1.length; _i++) {
+ var marker = markers_1[_i];
+ var id = marker.id;
+ if (id in hash) {
+ index.remove(hash[id]);
+ updated.push(marker);
+ }
+ var item = {
+ lat: marker.latLon.lat,
+ lon: marker.latLon.lon,
+ marker: marker,
+ };
+ hash[id] = item;
+ index.insert(item);
+ }
+ if (updated.length > 0) {
+ this._updated$.next(updated);
+ }
+ if (markers.length > updated.length) {
+ this._indexChanged$.next(this);
+ }
+ };
+ MarkerSet.prototype.has = function (id) {
+ return id in this._hash;
+ };
+ MarkerSet.prototype.get = function (id) {
+ return this.has(id) ? this._hash[id].marker : undefined;
+ };
+ MarkerSet.prototype.getAll = function () {
+ return this._index
+ .all()
+ .map(function (indexItem) {
+ return indexItem.marker;
+ });
+ };
+ MarkerSet.prototype.remove = function (ids) {
+ var hash = this._hash;
+ var index = this._index;
+ var changed = false;
+ for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
+ var id = ids_1[_i];
+ if (!(id in hash)) {
+ continue;
+ }
+ var item = hash[id];
+ index.remove(item);
+ delete hash[id];
+ changed = true;
+ }
+ if (changed) {
+ this._indexChanged$.next(this);
+ }
+ };
+ MarkerSet.prototype.removeAll = function () {
+ this._hash = {};
+ this._index.clear();
+ this._indexChanged$.next(this);
+ };
+ MarkerSet.prototype.search = function (_a) {
+ var sw = _a[0], ne = _a[1];
+ return this._index
+ .search({ maxX: ne.lon, maxY: ne.lat, minX: sw.lon, minY: sw.lat })
+ .map(function (indexItem) {
+ return indexItem.marker;
+ });
+ };
+ MarkerSet.prototype.update = function (marker) {
+ var hash = this._hash;
+ var index = this._index;
+ var id = marker.id;
+ if (!(id in hash)) {
+ return;
+ }
+ index.remove(hash[id]);
+ var item = {
+ lat: marker.latLon.lat,
+ lon: marker.latLon.lon,
+ marker: marker,
+ };
+ hash[id] = item;
+ index.insert(item);
+ };
+ return MarkerSet;
+}());
+exports.MarkerSet = MarkerSet;
+exports.default = MarkerSet;
+
+},{"rbush":26,"rxjs":27}],319:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var Component_1 = require("../../../Component");
+/**
+ * @class CircleMarker
+ *
+ * @classdesc Non-interactive marker with a flat circle shape. The circle
+ * marker can not be configured to be interactive.
+ *
+ * Circle marker properties can not be updated after creation.
+ *
+ * To create and add one `CircleMarker` with default configuration
+ * and one with configuration use
+ *
+ * @example
+ * ```
+ * var defaultMarker = new Mapillary.MarkerComponent.CircleMarker(
+ * "id-1",
+ * { lat: 0, lon: 0, });
+ *
+ * var configuredMarker = new Mapillary.MarkerComponent.CircleMarker(
+ * "id-2",
+ * { lat: 0, lon: 0, },
+ * {
+ * color: "#0Ff",
+ * opacity: 0.3,
+ * radius: 0.7,
+ * });
+ *
+ * markerComponent.add([defaultMarker, configuredMarker]);
+ * ```
+ */
+var CircleMarker = /** @class */ (function (_super) {
+ __extends(CircleMarker, _super);
+ function CircleMarker(id, latLon, options) {
+ var _this = _super.call(this, id, latLon) || this;
+ options = !!options ? options : {};
+ _this._color = options.color != null ? options.color : 0xffffff;
+ _this._opacity = options.opacity != null ? options.opacity : 0.4;
+ _this._radius = options.radius != null ? options.radius : 1;
+ return _this;
+ }
+ CircleMarker.prototype._createGeometry = function (position) {
+ var circle = new THREE.Mesh(new THREE.CircleGeometry(this._radius, 16), new THREE.MeshBasicMaterial({
+ color: this._color,
+ opacity: this._opacity,
+ transparent: true,
+ }));
+ circle.up.fromArray([0, 0, 1]);
+ circle.renderOrder = -1;
+ var group = new THREE.Object3D();
+ group.add(circle);
+ group.position.fromArray(position);
+ this._geometry = group;
+ };
+ CircleMarker.prototype._disposeGeometry = function () {
+ for (var _i = 0, _a = this._geometry.children; _i < _a.length; _i++) {
+ var mesh = _a[_i];
+ mesh.geometry.dispose();
+ mesh.material.dispose();
+ }
+ };
+ CircleMarker.prototype._getInteractiveObjects = function () {
+ return [];
+ };
+ return CircleMarker;
+}(Component_1.Marker));
+exports.CircleMarker = CircleMarker;
+exports.default = CircleMarker;
+
+},{"../../../Component":275,"three":226}],320:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * @class Marker
+ *
+ * @classdesc Represents an abstract marker class that should be extended
+ * by marker implementations used in the marker component.
+ */
+var Marker = /** @class */ (function () {
+ function Marker(id, latLon) {
+ this._id = id;
+ this._latLon = latLon;
+ }
+ Object.defineProperty(Marker.prototype, "id", {
+ /**
+ * Get id.
+ * @returns {string} The id of the marker.
+ */
+ get: function () {
+ return this._id;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Marker.prototype, "geometry", {
+ /**
+ * Get geometry.
+ *
+ * @ignore
+ */
+ get: function () {
+ return this._geometry;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Marker.prototype, "latLon", {
+ /**
+ * Get lat lon.
+ * @returns {ILatLon} The geographic coordinates of the marker.
+ */
+ get: function () {
+ return this._latLon;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /** @ignore */
+ Marker.prototype.createGeometry = function (position) {
+ if (!!this._geometry) {
+ return;
+ }
+ this._createGeometry(position);
+ // update matrix world if raycasting occurs before first render
+ this._geometry.updateMatrixWorld(true);
+ };
+ /** @ignore */
+ Marker.prototype.disposeGeometry = function () {
+ if (!this._geometry) {
+ return;
+ }
+ this._disposeGeometry();
+ this._geometry = undefined;
+ };
+ /** @ignore */
+ Marker.prototype.getInteractiveObjects = function () {
+ if (!this._geometry) {
+ return [];
+ }
+ return this._getInteractiveObjects();
+ };
+ /** @ignore */
+ Marker.prototype.lerpAltitude = function (alt, alpha) {
+ if (!this._geometry) {
+ return;
+ }
+ this._geometry.position.z = (1 - alpha) * this._geometry.position.z + alpha * alt;
+ };
+ /** @ignore */
+ Marker.prototype.updatePosition = function (position, latLon) {
+ if (!!latLon) {
+ this._latLon.lat = latLon.lat;
+ this._latLon.lon = latLon.lon;
+ }
+ if (!this._geometry) {
+ return;
+ }
+ this._geometry.position.fromArray(position);
+ this._geometry.updateMatrixWorld(true);
+ };
+ return Marker;
+}());
+exports.Marker = Marker;
+exports.default = Marker;
+
+},{}],321:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var Component_1 = require("../../../Component");
+/**
+ * @class SimpleMarker
+ *
+ * @classdesc Interactive marker with ice cream shape. The sphere
+ * inside the ice cream can be configured to be interactive.
+ *
+ * Simple marker properties can not be updated after creation.
+ *
+ * To create and add one `SimpleMarker` with default configuration
+ * (non-interactive) and one interactive with configuration use
+ *
+ * @example
+ * ```
+ * var defaultMarker = new Mapillary.MarkerComponent.SimpleMarker(
+ * "id-1",
+ * { lat: 0, lon: 0, });
+ *
+ * var interactiveMarker = new Mapillary.MarkerComponent.SimpleMarker(
+ * "id-2",
+ * { lat: 0, lon: 0, },
+ * {
+ * ballColor: "#00f",
+ * ballOpacity: 0.5,
+ * color: "#00f",
+ * interactive: true,
+ * opacity: 0.3,
+ * radius: 0.7,
+ * });
+ *
+ * markerComponent.add([defaultMarker, interactiveMarker]);
+ * ```
+ */
+var SimpleMarker = /** @class */ (function (_super) {
+ __extends(SimpleMarker, _super);
+ function SimpleMarker(id, latLon, options) {
+ var _this = _super.call(this, id, latLon) || this;
+ options = !!options ? options : {};
+ _this._ballColor = options.ballColor != null ? options.ballColor : 0xff0000;
+ _this._ballOpacity = options.ballOpacity != null ? options.ballOpacity : 0.8;
+ _this._circleToRayAngle = 2;
+ _this._color = options.color != null ? options.color : 0xff0000;
+ _this._interactive = !!options.interactive;
+ _this._opacity = options.opacity != null ? options.opacity : 0.4;
+ _this._radius = options.radius != null ? options.radius : 1;
+ return _this;
+ }
+ SimpleMarker.prototype._createGeometry = function (position) {
+ var radius = this._radius;
+ var cone = new THREE.Mesh(this._markerGeometry(radius, 8, 8), new THREE.MeshBasicMaterial({
+ color: this._color,
+ opacity: this._opacity,
+ transparent: true,
+ }));
+ cone.renderOrder = 1;
+ var ball = new THREE.Mesh(new THREE.SphereGeometry(radius / 2, 8, 8), new THREE.MeshBasicMaterial({
+ color: this._ballColor,
+ opacity: this._ballOpacity,
+ transparent: true,
+ }));
+ ball.position.z = this._markerHeight(radius);
+ var group = new THREE.Object3D();
+ group.add(ball);
+ group.add(cone);
+ group.position.fromArray(position);
+ this._geometry = group;
+ };
+ SimpleMarker.prototype._disposeGeometry = function () {
+ for (var _i = 0, _a = this._geometry.children; _i < _a.length; _i++) {
+ var mesh = _a[_i];
+ mesh.geometry.dispose();
+ mesh.material.dispose();
+ }
+ };
+ SimpleMarker.prototype._getInteractiveObjects = function () {
+ return this._interactive ? [this._geometry.children[0]] : [];
+ };
+ SimpleMarker.prototype._markerHeight = function (radius) {
+ var t = Math.tan(Math.PI - this._circleToRayAngle);
+ return radius * Math.sqrt(1 + t * t);
+ };
+ SimpleMarker.prototype._markerGeometry = function (radius, widthSegments, heightSegments) {
+ var geometry = new THREE.Geometry();
+ widthSegments = Math.max(3, Math.floor(widthSegments) || 8);
+ heightSegments = Math.max(2, Math.floor(heightSegments) || 6);
+ var height = this._markerHeight(radius);
+ var vertices = [];
+ for (var y = 0; y <= heightSegments; ++y) {
+ var verticesRow = [];
+ for (var x = 0; x <= widthSegments; ++x) {
+ var u = x / widthSegments * Math.PI * 2;
+ var v = y / heightSegments * Math.PI;
+ var r = void 0;
+ if (v < this._circleToRayAngle) {
+ r = radius;
+ }
+ else {
+ var t = Math.tan(v - this._circleToRayAngle);
+ r = radius * Math.sqrt(1 + t * t);
+ }
+ var vertex = new THREE.Vector3();
+ vertex.x = r * Math.cos(u) * Math.sin(v);
+ vertex.y = r * Math.sin(u) * Math.sin(v);
+ vertex.z = r * Math.cos(v) + height;
+ geometry.vertices.push(vertex);
+ verticesRow.push(geometry.vertices.length - 1);
+ }
+ vertices.push(verticesRow);
+ }
+ for (var y = 0; y < heightSegments; ++y) {
+ for (var x = 0; x < widthSegments; ++x) {
+ var v1 = vertices[y][x + 1];
+ var v2 = vertices[y][x];
+ var v3 = vertices[y + 1][x];
+ var v4 = vertices[y + 1][x + 1];
+ var n1 = geometry.vertices[v1].clone().normalize();
+ var n2 = geometry.vertices[v2].clone().normalize();
+ var n3 = geometry.vertices[v3].clone().normalize();
+ var n4 = geometry.vertices[v4].clone().normalize();
+ geometry.faces.push(new THREE.Face3(v1, v2, v4, [n1, n2, n4]));
+ geometry.faces.push(new THREE.Face3(v2, v3, v4, [n2.clone(), n3, n4.clone()]));
+ }
+ }
+ geometry.computeFaceNormals();
+ geometry.boundingSphere = new THREE.Sphere(new THREE.Vector3(), radius + height);
+ return geometry;
+ };
+ return SimpleMarker;
+}(Component_1.Marker));
+exports.SimpleMarker = SimpleMarker;
+exports.default = SimpleMarker;
+
+},{"../../../Component":275,"three":226}],322:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+/**
+ * The `BounceHandler` ensures that the viewer bounces back to the image
+ * when drag panning outside of the image edge.
+ */
+var BounceHandler = /** @class */ (function (_super) {
+ __extends(BounceHandler, _super);
+ function BounceHandler(component, container, navigator, viewportCoords, spatial) {
+ var _this = _super.call(this, component, container, navigator) || this;
+ _this._spatial = spatial;
+ _this._viewportCoords = viewportCoords;
+ return _this;
+ }
+ BounceHandler.prototype._enable = function () {
+ var _this = this;
+ var inTransition$ = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return frame.state.alpha < 1;
+ }), operators_1.distinctUntilChanged());
+ this._bounceSubscription = rxjs_1.combineLatest(inTransition$, this._navigator.stateService.inTranslation$, this._container.mouseService.active$, this._container.touchService.active$).pipe(operators_1.map(function (noForce) {
+ return noForce[0] || noForce[1] || noForce[2] || noForce[3];
+ }), operators_1.distinctUntilChanged(), operators_1.switchMap(function (noForce) {
+ return noForce ?
+ rxjs_1.empty() :
+ rxjs_1.combineLatest(_this._container.renderService.renderCamera$, _this._navigator.stateService.currentTransform$.pipe(operators_1.first()));
+ }), operators_1.withLatestFrom(this._navigator.panService.panNodes$))
+ .subscribe(function (_a) {
+ var _b = _a[0], render = _b[0], transform = _b[1], nts = _a[1];
+ if (!transform.hasValidScale && render.camera.focal < 0.1) {
+ return;
+ }
+ if (render.perspective.aspect === 0 || render.perspective.aspect === Number.POSITIVE_INFINITY) {
+ return;
+ }
+ var distances = Component_1.ImageBoundary.viewportDistances(transform, render.perspective, _this._viewportCoords);
+ var basic = _this._viewportCoords.viewportToBasic(0, 0, transform, render.perspective);
+ if ((basic[0] < 0 || basic[0] > 1) && nts.length > 0) {
+ distances[0] = distances[2] = 0;
+ }
+ for (var _i = 0, nts_1 = nts; _i < nts_1.length; _i++) {
+ var _c = nts_1[_i], t = _c[1];
+ var d = Component_1.ImageBoundary.viewportDistances(t, render.perspective, _this._viewportCoords);
+ for (var i = 1; i < distances.length; i += 2) {
+ if (d[i] < distances[i]) {
+ distances[i] = d[i];
+ }
+ }
+ }
+ if (Math.max.apply(Math, distances) < 0.01) {
+ return;
+ }
+ var horizontalDistance = distances[1] - distances[3];
+ var verticalDistance = distances[0] - distances[2];
+ var currentDirection = _this._viewportCoords
+ .unprojectFromViewport(0, 0, render.perspective)
+ .sub(render.perspective.position);
+ var directionPhi = _this._viewportCoords
+ .unprojectFromViewport(horizontalDistance, 0, render.perspective)
+ .sub(render.perspective.position);
+ var directionTheta = _this._viewportCoords
+ .unprojectFromViewport(0, verticalDistance, render.perspective)
+ .sub(render.perspective.position);
+ var phi = (horizontalDistance > 0 ? 1 : -1) * directionPhi.angleTo(currentDirection);
+ var theta = (verticalDistance > 0 ? 1 : -1) * directionTheta.angleTo(currentDirection);
+ var threshold = Math.PI / 60;
+ var coeff = 1e-1;
+ phi = _this._spatial.clamp(coeff * phi, -threshold, threshold);
+ theta = _this._spatial.clamp(coeff * theta, -threshold, threshold);
+ _this._navigator.stateService.rotateUnbounded({ phi: phi, theta: theta });
+ });
+ };
+ BounceHandler.prototype._disable = function () {
+ this._bounceSubscription.unsubscribe();
+ };
+ BounceHandler.prototype._getConfiguration = function () {
+ return {};
+ };
+ return BounceHandler;
+}(Component_1.HandlerBase));
+exports.BounceHandler = BounceHandler;
+exports.default = BounceHandler;
+
+},{"../../Component":275,"rxjs":27,"rxjs/operators":225}],323:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+/**
+ * The `DoubleClickZoomHandler` allows the user to zoom the viewer image at a point by double clicking.
+ *
+ * @example
+ * ```
+ * var mouseComponent = viewer.getComponent("mouse");
+ *
+ * mouseComponent.doubleClickZoom.disable();
+ * mouseComponent.doubleClickZoom.enable();
+ *
+ * var isEnabled = mouseComponent.doubleClickZoom.isEnabled;
+ * ```
+ */
+var DoubleClickZoomHandler = /** @class */ (function (_super) {
+ __extends(DoubleClickZoomHandler, _super);
+ /** @ignore */
+ function DoubleClickZoomHandler(component, container, navigator, viewportCoords) {
+ var _this = _super.call(this, component, container, navigator) || this;
+ _this._viewportCoords = viewportCoords;
+ return _this;
+ }
+ DoubleClickZoomHandler.prototype._enable = function () {
+ var _this = this;
+ this._zoomSubscription = rxjs_1.merge(this._container.mouseService
+ .filtered$(this._component.name, this._container.mouseService.dblClick$), this._container.touchService.doubleTap$.pipe(operators_1.map(function (e) {
+ var touch = e.touches[0];
+ return { clientX: touch.clientX, clientY: touch.clientY, shiftKey: e.shiftKey };
+ }))).pipe(operators_1.withLatestFrom(this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$))
+ .subscribe(function (_a) {
+ var event = _a[0], render = _a[1], transform = _a[2];
+ var element = _this._container.element;
+ var _b = _this._viewportCoords.canvasPosition(event, element), canvasX = _b[0], canvasY = _b[1];
+ var unprojected = _this._viewportCoords.unprojectFromCanvas(canvasX, canvasY, element, render.perspective);
+ var reference = transform.projectBasic(unprojected.toArray());
+ var delta = !!event.shiftKey ? -1 : 1;
+ _this._navigator.stateService.zoomIn(delta, reference);
+ });
+ };
+ DoubleClickZoomHandler.prototype._disable = function () {
+ this._zoomSubscription.unsubscribe();
+ };
+ DoubleClickZoomHandler.prototype._getConfiguration = function (enable) {
+ return { doubleClickZoom: enable };
+ };
+ return DoubleClickZoomHandler;
+}(Component_1.HandlerBase));
+exports.DoubleClickZoomHandler = DoubleClickZoomHandler;
+exports.default = DoubleClickZoomHandler;
+
+},{"../../Component":275,"rxjs":27,"rxjs/operators":225}],324:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+/**
+ * The `DragPanHandler` allows the user to pan the viewer image by clicking and dragging the cursor.
+ *
+ * @example
+ * ```
+ * var mouseComponent = viewer.getComponent("mouse");
+ *
+ * mouseComponent.dragPan.disable();
+ * mouseComponent.dragPan.enable();
+ *
+ * var isEnabled = mouseComponent.dragPan.isEnabled;
+ * ```
+ */
+var DragPanHandler = /** @class */ (function (_super) {
+ __extends(DragPanHandler, _super);
+ /** @ignore */
+ function DragPanHandler(component, container, navigator, viewportCoords, spatial) {
+ var _this = _super.call(this, component, container, navigator) || this;
+ _this._spatial = spatial;
+ _this._viewportCoords = viewportCoords;
+ return _this;
+ }
+ DragPanHandler.prototype._enable = function () {
+ var _this = this;
+ var draggingStarted$ = this._container.mouseService
+ .filtered$(this._component.name, this._container.mouseService.mouseDragStart$).pipe(operators_1.map(function () {
+ return true;
+ }), operators_1.share());
+ var draggingStopped$ = this._container.mouseService
+ .filtered$(this._component.name, this._container.mouseService.mouseDragEnd$).pipe(operators_1.map(function () {
+ return false;
+ }), operators_1.share());
+ this._activeMouseSubscription = rxjs_1.merge(draggingStarted$, draggingStopped$)
+ .subscribe(this._container.mouseService.activate$);
+ var documentMouseMove$ = rxjs_1.merge(draggingStarted$, draggingStopped$).pipe(operators_1.switchMap(function (dragging) {
+ return dragging ?
+ _this._container.mouseService.documentMouseMove$ :
+ rxjs_1.empty();
+ }));
+ this._preventDefaultSubscription = rxjs_1.merge(documentMouseMove$, this._container.touchService.touchMove$)
+ .subscribe(function (event) {
+ event.preventDefault(); // prevent selection of content outside the viewer
+ });
+ var touchMovingStarted$ = this._container.touchService.singleTouchDragStart$.pipe(operators_1.map(function () {
+ return true;
+ }));
+ var touchMovingStopped$ = this._container.touchService.singleTouchDragEnd$.pipe(operators_1.map(function () {
+ return false;
+ }));
+ this._activeTouchSubscription = rxjs_1.merge(touchMovingStarted$, touchMovingStopped$)
+ .subscribe(this._container.touchService.activate$);
+ var rotation$ = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return frame.state.currentNode.fullPano || frame.state.nodesAhead < 1;
+ }), operators_1.distinctUntilChanged(), operators_1.switchMap(function (enable) {
+ if (!enable) {
+ return rxjs_1.empty();
+ }
+ var mouseDrag$ = Component_1.MouseOperator.filteredPairwiseMouseDrag$(_this._component.name, _this._container.mouseService);
+ var singleTouchDrag$ = rxjs_1.merge(_this._container.touchService.singleTouchDragStart$, _this._container.touchService.singleTouchDrag$, _this._container.touchService.singleTouchDragEnd$.pipe(operators_1.map(function () { return null; }))).pipe(operators_1.map(function (event) {
+ return event != null && event.touches.length > 0 ?
+ event.touches[0] : null;
+ }), operators_1.pairwise(), operators_1.filter(function (pair) {
+ return pair[0] != null && pair[1] != null;
+ }));
+ return rxjs_1.merge(mouseDrag$, singleTouchDrag$);
+ }), operators_1.withLatestFrom(this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$, this._navigator.panService.panNodes$), operators_1.map(function (_a) {
+ var events = _a[0], render = _a[1], transform = _a[2], nts = _a[3];
+ var previousEvent = events[0];
+ var event = events[1];
+ var movementX = event.clientX - previousEvent.clientX;
+ var movementY = event.clientY - previousEvent.clientY;
+ var element = _this._container.element;
+ var _b = _this._viewportCoords.canvasPosition(event, element), canvasX = _b[0], canvasY = _b[1];
+ var currentDirection = _this._viewportCoords.unprojectFromCanvas(canvasX, canvasY, element, render.perspective)
+ .sub(render.perspective.position);
+ var directionX = _this._viewportCoords.unprojectFromCanvas(canvasX - movementX, canvasY, element, render.perspective)
+ .sub(render.perspective.position);
+ var directionY = _this._viewportCoords.unprojectFromCanvas(canvasX, canvasY - movementY, element, render.perspective)
+ .sub(render.perspective.position);
+ var phi = (movementX > 0 ? 1 : -1) * directionX.angleTo(currentDirection);
+ var theta = (movementY > 0 ? -1 : 1) * directionY.angleTo(currentDirection);
+ var distances = Component_1.ImageBoundary.viewportDistances(transform, render.perspective, _this._viewportCoords);
+ for (var _i = 0, nts_1 = nts; _i < nts_1.length; _i++) {
+ var _c = nts_1[_i], t = _c[1];
+ var d = Component_1.ImageBoundary.viewportDistances(t, render.perspective, _this._viewportCoords);
+ for (var i = 0; i < distances.length; i++) {
+ if (d[i] < distances[i]) {
+ distances[i] = d[i];
+ }
+ }
+ }
+ if (distances[0] > 0 && theta < 0) {
+ theta /= Math.max(1, 2e2 * distances[0]);
+ }
+ if (distances[2] > 0 && theta > 0) {
+ theta /= Math.max(1, 2e2 * distances[2]);
+ }
+ if (distances[1] > 0 && phi < 0) {
+ phi /= Math.max(1, 2e2 * distances[1]);
+ }
+ if (distances[3] > 0 && phi > 0) {
+ phi /= Math.max(1, 2e2 * distances[3]);
+ }
+ return { phi: phi, theta: theta };
+ }), operators_1.share());
+ this._rotateWithoutInertiaSubscription = rotation$
+ .subscribe(function (rotation) {
+ _this._navigator.stateService.rotateWithoutInertia(rotation);
+ });
+ this._rotateSubscription = rotation$.pipe(operators_1.scan(function (rotationBuffer, rotation) {
+ _this._drainBuffer(rotationBuffer);
+ rotationBuffer.push([Date.now(), rotation]);
+ return rotationBuffer;
+ }, []), operators_1.sample(rxjs_1.merge(this._container.mouseService.filtered$(this._component.name, this._container.mouseService.mouseDragEnd$), this._container.touchService.singleTouchDragEnd$)), operators_1.map(function (rotationBuffer) {
+ var drainedBuffer = _this._drainBuffer(rotationBuffer.slice());
+ var rotation = { phi: 0, theta: 0 };
+ for (var _i = 0, drainedBuffer_1 = drainedBuffer; _i < drainedBuffer_1.length; _i++) {
+ var bufferedRotation = drainedBuffer_1[_i];
+ rotation.phi += bufferedRotation[1].phi;
+ rotation.theta += bufferedRotation[1].theta;
+ }
+ var count = drainedBuffer.length;
+ if (count > 0) {
+ rotation.phi /= count;
+ rotation.theta /= count;
+ }
+ var threshold = Math.PI / 18;
+ rotation.phi = _this._spatial.clamp(rotation.phi, -threshold, threshold);
+ rotation.theta = _this._spatial.clamp(rotation.theta, -threshold, threshold);
+ return rotation;
+ }))
+ .subscribe(function (rotation) {
+ _this._navigator.stateService.rotate(rotation);
+ });
+ };
+ DragPanHandler.prototype._disable = function () {
+ this._activeMouseSubscription.unsubscribe();
+ this._activeTouchSubscription.unsubscribe();
+ this._preventDefaultSubscription.unsubscribe();
+ this._rotateSubscription.unsubscribe();
+ this._rotateWithoutInertiaSubscription.unsubscribe();
+ this._activeMouseSubscription = null;
+ this._activeTouchSubscription = null;
+ this._preventDefaultSubscription = null;
+ this._rotateSubscription = null;
+ };
+ DragPanHandler.prototype._getConfiguration = function (enable) {
+ return { dragPan: enable };
+ };
+ DragPanHandler.prototype._drainBuffer = function (buffer) {
+ var cutoff = 50;
+ var now = Date.now();
+ while (buffer.length > 0 && now - buffer[0][0] > cutoff) {
+ buffer.shift();
+ }
+ return buffer;
+ };
+ return DragPanHandler;
+}(Component_1.HandlerBase));
+exports.DragPanHandler = DragPanHandler;
+exports.default = DragPanHandler;
+
+},{"../../Component":275,"rxjs":27,"rxjs/operators":225}],325:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+var State_1 = require("../../State");
+var EarthControlHandler = /** @class */ (function (_super) {
+ __extends(EarthControlHandler, _super);
+ function EarthControlHandler(component, container, navigator, viewportCoords, spatial) {
+ var _this = _super.call(this, component, container, navigator) || this;
+ _this._spatial = spatial;
+ _this._viewportCoords = viewportCoords;
+ return _this;
+ }
+ EarthControlHandler.prototype._enable = function () {
+ var _this = this;
+ var earth$ = this._navigator.stateService.state$.pipe(operators_1.map(function (state) {
+ return state === State_1.State.Earth;
+ }), operators_1.share());
+ this._preventDefaultSubscription = earth$.pipe(operators_1.switchMap(function (earth) {
+ return earth ?
+ _this._container.mouseService.mouseWheel$ :
+ rxjs_1.empty();
+ }))
+ .subscribe(function (event) {
+ event.preventDefault();
+ });
+ this._truckSubscription = earth$.pipe(operators_1.switchMap(function (earth) {
+ if (!earth) {
+ return rxjs_1.empty();
+ }
+ return Component_1.MouseOperator.filteredPairwiseMouseDrag$(_this._component.name, _this._container.mouseService).pipe(operators_1.filter(function (_a) {
+ var e1 = _a[0], e2 = _a[1];
+ return !(e1.ctrlKey && e2.ctrlKey);
+ }));
+ }), operators_1.withLatestFrom(this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$), operators_1.map(function (_a) {
+ var _b = _a[0], previous = _b[0], current = _b[1], render = _a[1], transform = _a[2];
+ var planeNormal = [0, 0, 1];
+ var planePoint = transform.unprojectBasic([0.5, 0.5], 0);
+ planePoint[2] -= 2;
+ var currentIntersection = _this._planeIntersection(current, planeNormal, planePoint, render.perspective, _this._container.element);
+ var previousIntersection = _this._planeIntersection(previous, planeNormal, planePoint, render.perspective, _this._container.element);
+ if (!currentIntersection || !previousIntersection) {
+ return null;
+ }
+ var direction = new THREE.Vector3()
+ .subVectors(currentIntersection, previousIntersection)
+ .multiplyScalar(-1)
+ .toArray();
+ return direction;
+ }), operators_1.filter(function (direction) {
+ return !!direction;
+ }))
+ .subscribe(function (direction) {
+ _this._navigator.stateService.truck(direction);
+ });
+ this._orbitSubscription = earth$.pipe(operators_1.switchMap(function (earth) {
+ if (!earth) {
+ return rxjs_1.empty();
+ }
+ return Component_1.MouseOperator.filteredPairwiseMouseDrag$(_this._component.name, _this._container.mouseService).pipe(operators_1.filter(function (_a) {
+ var e1 = _a[0], e2 = _a[1];
+ return e1.ctrlKey && e2.ctrlKey;
+ }));
+ }), operators_1.map(function (_a) {
+ var previous = _a[0], current = _a[1];
+ var _b = _this._eventToViewport(current, _this._container.element), currentX = _b[0], currentY = _b[1];
+ var _c = _this._eventToViewport(previous, _this._container.element), previousX = _c[0], previousY = _c[1];
+ var phi = (previousX - currentX) * Math.PI;
+ var theta = (currentY - previousY) * Math.PI / 2;
+ return { phi: phi, theta: theta };
+ }))
+ .subscribe(function (rotation) {
+ _this._navigator.stateService.orbit(rotation);
+ });
+ this._dollySubscription = earth$.pipe(operators_1.switchMap(function (earth) {
+ if (!earth) {
+ return rxjs_1.empty();
+ }
+ return _this._container.mouseService
+ .filteredWheel$(_this._component.name, _this._container.mouseService.mouseWheel$);
+ }), operators_1.map(function (event) {
+ var delta = event.deltaY;
+ if (event.deltaMode === 1) {
+ delta = 40 * delta;
+ }
+ else if (event.deltaMode === 2) {
+ delta = 800 * delta;
+ }
+ var canvasSize = _this._viewportCoords.containerToCanvas(_this._container.element);
+ return -delta / canvasSize[1];
+ }))
+ .subscribe(function (delta) {
+ _this._navigator.stateService.dolly(delta);
+ });
+ };
+ EarthControlHandler.prototype._disable = function () {
+ this._dollySubscription.unsubscribe();
+ this._orbitSubscription.unsubscribe();
+ this._preventDefaultSubscription.unsubscribe();
+ this._truckSubscription.unsubscribe();
+ };
+ EarthControlHandler.prototype._getConfiguration = function () {
+ return {};
+ };
+ EarthControlHandler.prototype._eventToViewport = function (event, element) {
+ var previousCanvas = this._viewportCoords.canvasPosition(event, element);
+ return this._viewportCoords.canvasToViewport(previousCanvas[0], previousCanvas[1], element);
+ };
+ EarthControlHandler.prototype._planeIntersection = function (event, planeNormal, planePoint, camera, element) {
+ var _a = this._viewportCoords.canvasPosition(event, element), canvasX = _a[0], canvasY = _a[1];
+ var direction = this._viewportCoords
+ .unprojectFromCanvas(canvasX, canvasY, element, camera)
+ .sub(camera.position)
+ .normalize();
+ if (Math.abs(this._spatial.angleToPlane(direction.toArray(), planeNormal)) < Math.PI / 90) {
+ return null;
+ }
+ var l0 = camera.position.clone();
+ var n = new THREE.Vector3().fromArray(planeNormal);
+ var p0 = new THREE.Vector3().fromArray(planePoint);
+ var d = new THREE.Vector3().subVectors(p0, l0).dot(n) / direction.clone().dot(n);
+ var intersection = new THREE.Vector3().addVectors(l0, direction.multiplyScalar(d));
+ if (this._viewportCoords.worldToCamera(intersection.toArray(), camera)[2] > 0) {
+ return null;
+ }
+ return intersection;
+ };
+ return EarthControlHandler;
+}(Component_1.HandlerBase));
+exports.EarthControlHandler = EarthControlHandler;
+exports.default = EarthControlHandler;
+
+},{"../../Component":275,"../../State":282,"rxjs":27,"rxjs/operators":225,"three":226}],326:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Geo_1 = require("../../../src/Geo");
+function basicBoundaryPoints(pointsPerSide) {
+ var points = [];
+ var os = [[0, 0], [1, 0], [1, 1], [0, 1]];
+ var ds = [[1, 0], [0, 1], [-1, 0], [0, -1]];
+ for (var side = 0; side < 4; ++side) {
+ var o = os[side];
+ var d = ds[side];
+ for (var i = 0; i < pointsPerSide; ++i) {
+ points.push([o[0] + d[0] * i / pointsPerSide,
+ o[1] + d[1] * i / pointsPerSide]);
+ }
+ }
+ return points;
+}
+function insideViewport(x, y) {
+ return x >= -1 && x <= 1 && y >= -1 && y <= 1;
+}
+function insideBasic(x, y) {
+ return x >= 0 && x <= 1 && y >= 0 && y <= 1;
+}
+function viewportDistances(transform, perspective, viewportCoords) {
+ var boundaryPointsBasic = basicBoundaryPoints(100);
+ var boundaryPointsViewport = boundaryPointsBasic
+ .map(function (basic) {
+ return viewportCoords.basicToViewportSafe(basic[0], basic[1], transform, perspective);
+ });
+ var visibleBoundaryPoints = [];
+ var viewportSides = [
+ { x: -1, y: 1 },
+ { x: 1, y: 1 },
+ { x: 1, y: -1 },
+ { x: -1, y: -1 }
+ ];
+ var intersections = [false, false, false, false];
+ for (var i = 0; i < boundaryPointsViewport.length; i++) {
+ var p1 = boundaryPointsViewport[i];
+ var p2 = boundaryPointsViewport[(i + 1) % boundaryPointsViewport.length];
+ if (p1 === null) {
+ continue;
+ }
+ if (p2 === null) {
+ if (insideViewport(p1[0], p1[1])) {
+ visibleBoundaryPoints.push(p1);
+ }
+ continue;
+ }
+ var x1 = p1[0], y1 = p1[1];
+ var x2 = p2[0], y2 = p2[1];
+ if (insideViewport(x1, y1)) {
+ if (insideViewport(x2, y2)) {
+ visibleBoundaryPoints.push(p1);
+ }
+ else {
+ for (var side = 0; side < 4; side++) {
+ var s1 = { p1: { x: x1, y: y1 }, p2: { x: x2, y: y2 } };
+ var s2 = { p1: viewportSides[side], p2: viewportSides[(side + 1) % 4] };
+ var intersecting = Geo_1.Lines.segmentsIntersect(s1, s2);
+ if (intersecting) {
+ var intersection = Geo_1.Lines.segmentIntersection(s1, s2);
+ visibleBoundaryPoints.push(p1, [intersection.x, intersection.y]);
+ intersections[side] = true;
+ }
+ }
+ }
+ }
+ }
+ var _a = viewportCoords.viewportToBasic(-1, 1, transform, perspective), topLeftBasicX = _a[0], topLeftBasicY = _a[1];
+ var _b = viewportCoords.viewportToBasic(1, 1, transform, perspective), topRightBasicX = _b[0], topRightBasicY = _b[1];
+ var _c = viewportCoords.viewportToBasic(1, -1, transform, perspective), bottomRightBasicX = _c[0], bottomRightBasicY = _c[1];
+ var _d = viewportCoords.viewportToBasic(-1, -1, transform, perspective), bottomLeftBasicX = _d[0], bottomLeftBasicY = _d[1];
+ if (insideBasic(topLeftBasicX, topLeftBasicY)) {
+ intersections[3] = intersections[0] = true;
+ }
+ if (insideBasic(topRightBasicX, topRightBasicY)) {
+ intersections[0] = intersections[1] = true;
+ }
+ if (insideBasic(bottomRightBasicX, bottomRightBasicY)) {
+ intersections[1] = intersections[2] = true;
+ }
+ if (insideBasic(bottomLeftBasicX, bottomLeftBasicY)) {
+ intersections[2] = intersections[3] = true;
+ }
+ var maximums = [-1, -1, 1, 1];
+ for (var _i = 0, visibleBoundaryPoints_1 = visibleBoundaryPoints; _i < visibleBoundaryPoints_1.length; _i++) {
+ var visibleBoundaryPoint = visibleBoundaryPoints_1[_i];
+ var x = visibleBoundaryPoint[0];
+ var y = visibleBoundaryPoint[1];
+ if (x > maximums[1]) {
+ maximums[1] = x;
+ }
+ if (x < maximums[3]) {
+ maximums[3] = x;
+ }
+ if (y > maximums[0]) {
+ maximums[0] = y;
+ }
+ if (y < maximums[2]) {
+ maximums[2] = y;
+ }
+ }
+ var boundary = [1, 1, -1, -1];
+ var distances = [];
+ for (var side = 0; side < 4; side++) {
+ if (intersections[side]) {
+ distances.push(0);
+ continue;
+ }
+ distances.push(Math.abs(boundary[side] - maximums[side]));
+ }
+ return distances;
+}
+exports.viewportDistances = viewportDistances;
+
+},{"../../../src/Geo":278}],327:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../Component");
+var Geo_1 = require("../../Geo");
+/**
+ * @class MouseComponent
+ *
+ * @classdesc Component handling mouse and touch events for camera movement.
+ *
+ * To retrive and use the mouse component
+ *
+ * @example
+ * ```
+ * var viewer = new Mapillary.Viewer(
+ * "<element-id>",
+ * "<client-id>",
+ * "<my key>");
+ *
+ * var mouseComponent = viewer.getComponent("mouse");
+ * ```
+ */
+var MouseComponent = /** @class */ (function (_super) {
+ __extends(MouseComponent, _super);
+ /** @ignore */
+ function MouseComponent(name, container, navigator) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ var spatial = new Geo_1.Spatial();
+ var viewportCoords = new Geo_1.ViewportCoords();
+ _this._bounceHandler = new Component_1.BounceHandler(_this, container, navigator, viewportCoords, spatial);
+ _this._doubleClickZoomHandler = new Component_1.DoubleClickZoomHandler(_this, container, navigator, viewportCoords);
+ _this._dragPanHandler = new Component_1.DragPanHandler(_this, container, navigator, viewportCoords, spatial);
+ _this._earthControlHandler = new Component_1.EarthControlHandler(_this, container, navigator, viewportCoords, spatial);
+ _this._scrollZoomHandler = new Component_1.ScrollZoomHandler(_this, container, navigator, viewportCoords);
+ _this._touchZoomHandler = new Component_1.TouchZoomHandler(_this, container, navigator, viewportCoords);
+ return _this;
+ }
+ Object.defineProperty(MouseComponent.prototype, "doubleClickZoom", {
+ /**
+ * Get double click zoom.
+ *
+ * @returns {DoubleClickZoomHandler} The double click zoom handler.
+ */
+ get: function () {
+ return this._doubleClickZoomHandler;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(MouseComponent.prototype, "dragPan", {
+ /**
+ * Get drag pan.
+ *
+ * @returns {DragPanHandler} The drag pan handler.
+ */
+ get: function () {
+ return this._dragPanHandler;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(MouseComponent.prototype, "scrollZoom", {
+ /**
+ * Get scroll zoom.
+ *
+ * @returns {ScrollZoomHandler} The scroll zoom handler.
+ */
+ get: function () {
+ return this._scrollZoomHandler;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(MouseComponent.prototype, "touchZoom", {
+ /**
+ * Get touch zoom.
+ *
+ * @returns {TouchZoomHandler} The touch zoom handler.
+ */
+ get: function () {
+ return this._touchZoomHandler;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ MouseComponent.prototype._activate = function () {
+ var _this = this;
+ this._bounceHandler.enable();
+ this._earthControlHandler.enable();
+ this._configurationSubscription = this._configuration$
+ .subscribe(function (configuration) {
+ if (configuration.doubleClickZoom) {
+ _this._doubleClickZoomHandler.enable();
+ }
+ else {
+ _this._doubleClickZoomHandler.disable();
+ }
+ if (configuration.dragPan) {
+ _this._dragPanHandler.enable();
+ }
+ else {
+ _this._dragPanHandler.disable();
+ }
+ if (configuration.scrollZoom) {
+ _this._scrollZoomHandler.enable();
+ }
+ else {
+ _this._scrollZoomHandler.disable();
+ }
+ if (configuration.touchZoom) {
+ _this._touchZoomHandler.enable();
+ }
+ else {
+ _this._touchZoomHandler.disable();
+ }
+ });
+ this._container.mouseService.claimMouse(this._name, 0);
+ };
+ MouseComponent.prototype._deactivate = function () {
+ this._container.mouseService.unclaimMouse(this._name);
+ this._configurationSubscription.unsubscribe();
+ this._bounceHandler.disable();
+ this._doubleClickZoomHandler.disable();
+ this._dragPanHandler.disable();
+ this._earthControlHandler.disable();
+ this._scrollZoomHandler.disable();
+ this._touchZoomHandler.disable();
+ };
+ MouseComponent.prototype._getDefaultConfiguration = function () {
+ return { doubleClickZoom: false, dragPan: true, scrollZoom: true, touchZoom: true };
+ };
+ /** @inheritdoc */
+ MouseComponent.componentName = "mouse";
+ return MouseComponent;
+}(Component_1.Component));
+exports.MouseComponent = MouseComponent;
+Component_1.ComponentService.register(MouseComponent);
+exports.default = MouseComponent;
+
+},{"../../Component":275,"../../Geo":278}],328:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+/**
+ * The `ScrollZoomHandler` allows the user to zoom the viewer image by scrolling.
+ *
+ * @example
+ * ```
+ * var mouseComponent = viewer.getComponent("mouse");
+ *
+ * mouseComponent.scrollZoom.disable();
+ * mouseComponent.scrollZoom.enable();
+ *
+ * var isEnabled = mouseComponent.scrollZoom.isEnabled;
+ * ```
+ */
+var ScrollZoomHandler = /** @class */ (function (_super) {
+ __extends(ScrollZoomHandler, _super);
+ /** @ignore */
+ function ScrollZoomHandler(component, container, navigator, viewportCoords) {
+ var _this = _super.call(this, component, container, navigator) || this;
+ _this._viewportCoords = viewportCoords;
+ return _this;
+ }
+ ScrollZoomHandler.prototype._enable = function () {
+ var _this = this;
+ this._container.mouseService.claimWheel(this._component.name, 0);
+ this._preventDefaultSubscription = this._container.mouseService.mouseWheel$
+ .subscribe(function (event) {
+ event.preventDefault();
+ });
+ this._zoomSubscription = this._container.mouseService
+ .filteredWheel$(this._component.name, this._container.mouseService.mouseWheel$).pipe(operators_1.withLatestFrom(this._navigator.stateService.currentState$, function (w, f) {
+ return [w, f];
+ }), operators_1.filter(function (args) {
+ var state = args[1].state;
+ return state.currentNode.fullPano || state.nodesAhead < 1;
+ }), operators_1.map(function (args) {
+ return args[0];
+ }), operators_1.withLatestFrom(this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$, function (w, r, t) {
+ return [w, r, t];
+ }))
+ .subscribe(function (args) {
+ var event = args[0];
+ var render = args[1];
+ var transform = args[2];
+ var element = _this._container.element;
+ var _a = _this._viewportCoords.canvasPosition(event, element), canvasX = _a[0], canvasY = _a[1];
+ var unprojected = _this._viewportCoords.unprojectFromCanvas(canvasX, canvasY, element, render.perspective);
+ var reference = transform.projectBasic(unprojected.toArray());
+ var deltaY = event.deltaY;
+ if (event.deltaMode === 1) {
+ deltaY = 40 * deltaY;
+ }
+ else if (event.deltaMode === 2) {
+ deltaY = 800 * deltaY;
+ }
+ var canvasSize = _this._viewportCoords.containerToCanvas(element);
+ var zoom = -3 * deltaY / canvasSize[1];
+ _this._navigator.stateService.zoomIn(zoom, reference);
+ });
+ };
+ ScrollZoomHandler.prototype._disable = function () {
+ this._container.mouseService.unclaimWheel(this._component.name);
+ this._preventDefaultSubscription.unsubscribe();
+ this._zoomSubscription.unsubscribe();
+ this._preventDefaultSubscription = null;
+ this._zoomSubscription = null;
+ };
+ ScrollZoomHandler.prototype._getConfiguration = function (enable) {
+ return { scrollZoom: enable };
+ };
+ return ScrollZoomHandler;
+}(Component_1.HandlerBase));
+exports.ScrollZoomHandler = ScrollZoomHandler;
+exports.default = ScrollZoomHandler;
+
+},{"../../Component":275,"rxjs/operators":225}],329:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+/**
+ * The `TouchZoomHandler` allows the user to zoom the viewer image by pinching on a touchscreen.
+ *
+ * @example
+ * ```
+ * var mouseComponent = viewer.getComponent("mouse");
+ *
+ * mouseComponent.touchZoom.disable();
+ * mouseComponent.touchZoom.enable();
+ *
+ * var isEnabled = mouseComponent.touchZoom.isEnabled;
+ * ```
+ */
+var TouchZoomHandler = /** @class */ (function (_super) {
+ __extends(TouchZoomHandler, _super);
+ /** @ignore */
+ function TouchZoomHandler(component, container, navigator, viewportCoords) {
+ var _this = _super.call(this, component, container, navigator) || this;
+ _this._viewportCoords = viewportCoords;
+ return _this;
+ }
+ TouchZoomHandler.prototype._enable = function () {
+ var _this = this;
+ this._preventDefaultSubscription = this._container.touchService.pinch$
+ .subscribe(function (pinch) {
+ pinch.originalEvent.preventDefault();
+ });
+ var pinchStarted$ = this._container.touchService.pinchStart$.pipe(operators_1.map(function (event) {
+ return true;
+ }));
+ var pinchStopped$ = this._container.touchService.pinchEnd$.pipe(operators_1.map(function (event) {
+ return false;
+ }));
+ this._activeSubscription = rxjs_1.merge(pinchStarted$, pinchStopped$)
+ .subscribe(this._container.touchService.activate$);
+ this._zoomSubscription = this._container.touchService.pinch$.pipe(operators_1.withLatestFrom(this._navigator.stateService.currentState$), operators_1.filter(function (args) {
+ var state = args[1].state;
+ return state.currentNode.fullPano || state.nodesAhead < 1;
+ }), operators_1.map(function (args) {
+ return args[0];
+ }), operators_1.withLatestFrom(this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$))
+ .subscribe(function (_a) {
+ var pinch = _a[0], render = _a[1], transform = _a[2];
+ var element = _this._container.element;
+ var _b = _this._viewportCoords.canvasPosition(pinch, element), canvasX = _b[0], canvasY = _b[1];
+ var unprojected = _this._viewportCoords.unprojectFromCanvas(canvasX, canvasY, element, render.perspective);
+ var reference = transform.projectBasic(unprojected.toArray());
+ var _c = _this._viewportCoords.containerToCanvas(element), canvasWidth = _c[0], canvasHeight = _c[1];
+ var zoom = 3 * pinch.distanceChange / Math.min(canvasWidth, canvasHeight);
+ _this._navigator.stateService.zoomIn(zoom, reference);
+ });
+ };
+ TouchZoomHandler.prototype._disable = function () {
+ this._activeSubscription.unsubscribe();
+ this._preventDefaultSubscription.unsubscribe();
+ this._zoomSubscription.unsubscribe();
+ this._preventDefaultSubscription = null;
+ this._zoomSubscription = null;
+ };
+ TouchZoomHandler.prototype._getConfiguration = function (enable) {
+ return { touchZoom: enable };
+ };
+ return TouchZoomHandler;
+}(Component_1.HandlerBase));
+exports.TouchZoomHandler = TouchZoomHandler;
+exports.default = TouchZoomHandler;
+
+},{"../../Component":275,"rxjs":27,"rxjs/operators":225}],330:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Popup_1 = require("./popup/Popup");
+exports.Popup = Popup_1.Popup;
+var PopupComponent_1 = require("./PopupComponent");
+exports.PopupComponent = PopupComponent_1.PopupComponent;
+
+},{"./PopupComponent":331,"./popup/Popup":332}],331:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+var Utils_1 = require("../../Utils");
+/**
+ * @class PopupComponent
+ *
+ * @classdesc Component for showing HTML popup objects.
+ *
+ * The `add` method is used for adding new popups. Popups are removed by reference.
+ *
+ * It is not possible to update popups in the set by updating any properties
+ * directly on the popup object. Popups need to be replaced by
+ * removing them and creating new ones with relevant changed properties and
+ * adding those instead.
+ *
+ * Popups are only relevant to a single image because they are based on
+ * 2D basic image coordinates. Popups related to a certain image should
+ * be removed when the viewer is moved to another node.
+ *
+ * To retrive and use the popup component
+ *
+ * @example
+ * ```
+ * var viewer = new Mapillary.Viewer(
+ * "<element-id>",
+ * "<client-id>",
+ * "<my key>",
+ * { component: { popup: true } });
+ *
+ * var popupComponent = viewer.getComponent("popup");
+ * ```
+ */
+var PopupComponent = /** @class */ (function (_super) {
+ __extends(PopupComponent, _super);
+ /** @ignore */
+ function PopupComponent(name, container, navigator, dom) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._dom = !!dom ? dom : new Utils_1.DOM();
+ _this._popups = [];
+ _this._added$ = new rxjs_1.Subject();
+ _this._popups$ = new rxjs_1.Subject();
+ return _this;
+ }
+ /**
+ * Add popups to the popups set.
+ *
+ * @description Adding a new popup never replaces an old one
+ * because they are stored by reference. Adding an already
+ * existing popup has no effect.
+ *
+ * @param {Array<Popup>} popups - Popups to add.
+ *
+ * @example ```popupComponent.add([popup1, popup2]);```
+ */
+ PopupComponent.prototype.add = function (popups) {
+ for (var _i = 0, popups_1 = popups; _i < popups_1.length; _i++) {
+ var popup = popups_1[_i];
+ if (this._popups.indexOf(popup) !== -1) {
+ continue;
+ }
+ this._popups.push(popup);
+ if (this._activated) {
+ popup.setParentContainer(this._popupContainer);
+ }
+ }
+ this._added$.next(popups);
+ this._popups$.next(this._popups);
+ };
+ /**
+ * Returns an array of all popups.
+ *
+ * @example ```var popups = popupComponent.getAll();```
+ */
+ PopupComponent.prototype.getAll = function () {
+ return this._popups.slice();
+ };
+ /**
+ * Remove popups based on reference from the popup set.
+ *
+ * @param {Array<Popup>} popups - Popups to remove.
+ *
+ * @example ```popupComponent.remove([popup1, popup2]);```
+ */
+ PopupComponent.prototype.remove = function (popups) {
+ for (var _i = 0, popups_2 = popups; _i < popups_2.length; _i++) {
+ var popup = popups_2[_i];
+ this._remove(popup);
+ }
+ this._popups$.next(this._popups);
+ };
+ /**
+ * Remove all popups from the popup set.
+ *
+ * @example ```popupComponent.removeAll();```
+ */
+ PopupComponent.prototype.removeAll = function () {
+ for (var _i = 0, _a = this._popups.slice(); _i < _a.length; _i++) {
+ var popup = _a[_i];
+ this._remove(popup);
+ }
+ this._popups$.next(this._popups);
+ };
+ PopupComponent.prototype._activate = function () {
+ var _this = this;
+ this._popupContainer = this._dom.createElement("div", "mapillary-js-popup-container", this._container.element);
+ for (var _i = 0, _a = this._popups; _i < _a.length; _i++) {
+ var popup = _a[_i];
+ popup.setParentContainer(this._popupContainer);
+ }
+ this._updateAllSubscription = rxjs_1.combineLatest(this._container.renderService.renderCamera$, this._container.renderService.size$, this._navigator.stateService.currentTransform$)
+ .subscribe(function (_a) {
+ var renderCamera = _a[0], size = _a[1], transform = _a[2];
+ for (var _i = 0, _b = _this._popups; _i < _b.length; _i++) {
+ var popup = _b[_i];
+ popup.update(renderCamera, size, transform);
+ }
+ });
+ var changed$ = this._popups$.pipe(operators_1.startWith(this._popups), operators_1.switchMap(function (popups) {
+ return rxjs_1.from(popups).pipe(operators_1.mergeMap(function (popup) {
+ return popup.changed$;
+ }));
+ }), operators_1.map(function (popup) {
+ return [popup];
+ }));
+ this._updateAddedChangedSubscription = rxjs_1.merge(this._added$, changed$).pipe(operators_1.withLatestFrom(this._container.renderService.renderCamera$, this._container.renderService.size$, this._navigator.stateService.currentTransform$))
+ .subscribe(function (_a) {
+ var popups = _a[0], renderCamera = _a[1], size = _a[2], transform = _a[3];
+ for (var _i = 0, popups_3 = popups; _i < popups_3.length; _i++) {
+ var popup = popups_3[_i];
+ popup.update(renderCamera, size, transform);
+ }
+ });
+ };
+ PopupComponent.prototype._deactivate = function () {
+ this._updateAllSubscription.unsubscribe();
+ this._updateAddedChangedSubscription.unsubscribe();
+ for (var _i = 0, _a = this._popups; _i < _a.length; _i++) {
+ var popup = _a[_i];
+ popup.remove();
+ }
+ this._container.element.removeChild(this._popupContainer);
+ delete this._popupContainer;
+ };
+ PopupComponent.prototype._getDefaultConfiguration = function () {
+ return {};
+ };
+ PopupComponent.prototype._remove = function (popup) {
+ var index = this._popups.indexOf(popup);
+ if (index === -1) {
+ return;
+ }
+ var removed = this._popups.splice(index, 1)[0];
+ if (this._activated) {
+ removed.remove();
+ }
+ };
+ PopupComponent.componentName = "popup";
+ return PopupComponent;
+}(Component_1.Component));
+exports.PopupComponent = PopupComponent;
+Component_1.ComponentService.register(PopupComponent);
+exports.default = PopupComponent;
+
+},{"../../Component":275,"../../Utils":285,"rxjs":27,"rxjs/operators":225}],332:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var Geo_1 = require("../../../Geo");
+var Utils_1 = require("../../../Utils");
+var Viewer_1 = require("../../../Viewer");
+/**
+ * @class Popup
+ *
+ * @classdesc Popup instance for rendering custom HTML content
+ * on top of images. Popups are based on 2D basic image coordinates
+ * (see the {@link Viewer} class documentation for more information about coordinate
+ * systems) and a certain popup is therefore only relevant to a single image.
+ * Popups related to a certain image should be removed when moving
+ * to another image.
+ *
+ * A popup must have both its content and its point or rect set to be
+ * rendered. Popup options can not be updated after creation but the
+ * basic point or rect as well as its content can be changed by calling
+ * the appropriate methods.
+ *
+ * To create and add one `Popup` with default configuration
+ * (tooltip visuals and automatic float) and one with specific options
+ * use
+ *
+ * @example
+ * ```
+ * var defaultSpan = document.createElement('span');
+ * defaultSpan.innerHTML = 'hello default';
+ *
+ * var defaultPopup = new Mapillary.PopupComponent.Popup();
+ * defaultPopup.setDOMContent(defaultSpan);
+ * defaultPopup.setBasicPoint([0.3, 0.3]);
+ *
+ * var cleanSpan = document.createElement('span');
+ * cleanSpan.innerHTML = 'hello clean';
+ *
+ * var cleanPopup = new Mapillary.PopupComponent.Popup({
+ * clean: true,
+ * float: Mapillary.Alignment.Top,
+ * offset: 10,
+ * opacity: 0.7,
+ * });
+ *
+ * cleanPopup.setDOMContent(cleanSpan);
+ * cleanPopup.setBasicPoint([0.6, 0.6]);
+ *
+ * popupComponent.add([defaultPopup, cleanPopup]);
+ * ```
+ *
+ * @description Implementation of API methods and API documentation inspired
+ * by/used from https://github.com/mapbox/mapbox-gl-js/blob/v0.38.0/src/ui/popup.js
+ */
+var Popup = /** @class */ (function () {
+ function Popup(options, viewportCoords, dom) {
+ this._options = {};
+ options = !!options ? options : {};
+ this._options.capturePointer = options.capturePointer === false ?
+ options.capturePointer : true;
+ this._options.clean = options.clean;
+ this._options.float = options.float;
+ this._options.offset = options.offset;
+ this._options.opacity = options.opacity;
+ this._options.position = options.position;
+ this._dom = !!dom ? dom : new Utils_1.DOM();
+ this._viewportCoords = !!viewportCoords ? viewportCoords : new Geo_1.ViewportCoords();
+ this._notifyChanged$ = new rxjs_1.Subject();
+ }
+ Object.defineProperty(Popup.prototype, "changed$", {
+ /**
+ * @description Internal observable used by the component to
+ * render the popup when its position or content has changed.
+ * @ignore
+ */
+ get: function () {
+ return this._notifyChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * @description Internal method used by the component to
+ * remove all references to the popup.
+ * @ignore
+ */
+ Popup.prototype.remove = function () {
+ if (this._content && this._content.parentNode) {
+ this._content.parentNode.removeChild(this._content);
+ }
+ if (this._container) {
+ this._container.parentNode.removeChild(this._container);
+ delete this._container;
+ }
+ if (this._parentContainer) {
+ delete this._parentContainer;
+ }
+ };
+ /**
+ * Sets a 2D basic image coordinates point to the popup's anchor, and
+ * moves the popup to it.
+ *
+ * @description Overwrites any previously set point or rect.
+ *
+ * @param {Array<number>} basicPoint - Point in 2D basic image coordinates.
+ *
+ * @example
+ * ```
+ * var popup = new Mapillary.PopupComponent.Popup();
+ * popup.setText('hello image');
+ * popup.setBasicPoint([0.3, 0.3]);
+ *
+ * popupComponent.add([popup]);
+ * ```
+ */
+ Popup.prototype.setBasicPoint = function (basicPoint) {
+ this._point = basicPoint.slice();
+ this._rect = null;
+ this._notifyChanged$.next(this);
+ };
+ /**
+ * Sets a 2D basic image coordinates rect to the popup's anchor, and
+ * moves the popup to it.
+ *
+ * @description Overwrites any previously set point or rect.
+ *
+ * @param {Array<number>} basicRect - Rect in 2D basic image
+ * coordinates ([topLeftX, topLeftY, bottomRightX, bottomRightY]) .
+ *
+ * @example
+ * ```
+ * var popup = new Mapillary.PopupComponent.Popup();
+ * popup.setText('hello image');
+ * popup.setBasicRect([0.3, 0.3, 0.5, 0.6]);
+ *
+ * popupComponent.add([popup]);
+ * ```
+ */
+ Popup.prototype.setBasicRect = function (basicRect) {
+ this._rect = basicRect.slice();
+ this._point = null;
+ this._notifyChanged$.next(this);
+ };
+ /**
+ * Sets the popup's content to the element provided as a DOM node.
+ *
+ * @param {Node} htmlNode - A DOM node to be used as content for the popup.
+ *
+ * @example
+ * ```
+ * var div = document.createElement('div');
+ * div.innerHTML = 'hello image';
+ *
+ * var popup = new Mapillary.PopupComponent.Popup();
+ * popup.setDOMContent(div);
+ * popup.setBasicPoint([0.3, 0.3]);
+ *
+ * popupComponent.add([popup]);
+ * ```
+ */
+ Popup.prototype.setDOMContent = function (htmlNode) {
+ if (this._content && this._content.parentNode) {
+ this._content.parentNode.removeChild(this._content);
+ }
+ var className = "mapillaryjs-popup-content" +
+ (this._options.clean === true ? "-clean" : "") +
+ (this._options.capturePointer === true ? " mapillaryjs-popup-capture-pointer" : "");
+ this._content = this._dom.createElement("div", className, this._container);
+ this._content.appendChild(htmlNode);
+ this._notifyChanged$.next(this);
+ };
+ /**
+ * Sets the popup's content to the HTML provided as a string.
+ *
+ * @description This method does not perform HTML filtering or sanitization,
+ * and must be used only with trusted content. Consider Popup#setText if the
+ * content is an untrusted text string.
+ *
+ * @param {string} html - A string representing HTML content for the popup.
+ *
+ * @example
+ * ```
+ * var popup = new Mapillary.PopupComponent.Popup();
+ * popup.setHTML('<div>hello image</div>');
+ * popup.setBasicPoint([0.3, 0.3]);
+ *
+ * popupComponent.add([popup]);
+ * ```
+ */
+ Popup.prototype.setHTML = function (html) {
+ var frag = this._dom.document.createDocumentFragment();
+ var temp = this._dom.createElement("body");
+ var child;
+ temp.innerHTML = html;
+ while (true) {
+ child = temp.firstChild;
+ if (!child) {
+ break;
+ }
+ frag.appendChild(child);
+ }
+ this.setDOMContent(frag);
+ };
+ /**
+ * Sets the popup's content to a string of text.
+ *
+ * @description This function creates a Text node in the DOM, so it cannot insert raw HTML.
+ * Use this method for security against XSS if the popup content is user-provided.
+ *
+ * @param {string} text - Textual content for the popup.
+ *
+ * @example
+ * ```
+ * var popup = new Mapillary.PopupComponent.Popup();
+ * popup.setText('hello image');
+ * popup.setBasicPoint([0.3, 0.3]);
+ *
+ * popupComponent.add([popup]);
+ * ```
+ */
+ Popup.prototype.setText = function (text) {
+ this.setDOMContent(this._dom.document.createTextNode(text));
+ };
+ /**
+ * @description Internal method for attaching the popup to
+ * its parent container so that it is rendered in the DOM tree.
+ * @ignore
+ */
+ Popup.prototype.setParentContainer = function (parentContainer) {
+ this._parentContainer = parentContainer;
+ };
+ /**
+ * @description Internal method for updating the rendered
+ * position of the popup called by the popup component.
+ * @ignore
+ */
+ Popup.prototype.update = function (renderCamera, size, transform) {
+ var _a;
+ if (!this._parentContainer || !this._content) {
+ return;
+ }
+ if (!this._point && !this._rect) {
+ return;
+ }
+ if (!this._container) {
+ this._container = this._dom.createElement("div", "mapillaryjs-popup", this._parentContainer);
+ var showTip = this._options.clean !== true &&
+ this._options.float !== Viewer_1.Alignment.Center;
+ if (showTip) {
+ var tipClassName = "mapillaryjs-popup-tip" +
+ (this._options.capturePointer === true ? " mapillaryjs-popup-capture-pointer" : "");
+ this._tip = this._dom.createElement("div", tipClassName, this._container);
+ this._dom.createElement("div", "mapillaryjs-popup-tip-inner", this._tip);
+ }
+ this._container.appendChild(this._content);
+ this._parentContainer.appendChild(this._container);
+ if (this._options.opacity != null) {
+ this._container.style.opacity = this._options.opacity.toString();
+ }
+ }
+ var pointPixel = null;
+ var position = this._alignmentToPopupAligment(this._options.position);
+ var float = this._alignmentToPopupAligment(this._options.float);
+ var classList = this._container.classList;
+ if (this._point != null) {
+ pointPixel =
+ this._viewportCoords.basicToCanvasSafe(this._point[0], this._point[1], { offsetHeight: size.height, offsetWidth: size.width }, transform, renderCamera.perspective);
+ }
+ else {
+ var alignments = ["center", "top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right"];
+ var appliedPosition = null;
+ for (var _i = 0, alignments_1 = alignments; _i < alignments_1.length; _i++) {
+ var alignment = alignments_1[_i];
+ if (classList.contains("mapillaryjs-popup-float-" + alignment)) {
+ appliedPosition = alignment;
+ break;
+ }
+ }
+ _a = this._rectToPixel(this._rect, position, appliedPosition, renderCamera, size, transform), pointPixel = _a[0], position = _a[1];
+ if (!float) {
+ float = position;
+ }
+ }
+ if (pointPixel == null) {
+ this._container.style.display = "none";
+ return;
+ }
+ this._container.style.display = "";
+ if (!float) {
+ var width = this._container.offsetWidth;
+ var height = this._container.offsetHeight;
+ var floats = this._pixelToFloats(pointPixel, size, width, height);
+ float = floats.length === 0 ? "top" : floats.join("-");
+ }
+ var offset = this._normalizeOffset(this._options.offset);
+ pointPixel = [pointPixel[0] + offset[float][0], pointPixel[1] + offset[float][1]];
+ pointPixel = [Math.round(pointPixel[0]), Math.round(pointPixel[1])];
+ var floatTranslate = {
+ "bottom": "translate(-50%,0)",
+ "bottom-left": "translate(-100%,0)",
+ "bottom-right": "translate(0,0)",
+ "center": "translate(-50%,-50%)",
+ "left": "translate(-100%,-50%)",
+ "right": "translate(0,-50%)",
+ "top": "translate(-50%,-100%)",
+ "top-left": "translate(-100%,-100%)",
+ "top-right": "translate(0,-100%)",
+ };
+ for (var key in floatTranslate) {
+ if (!floatTranslate.hasOwnProperty(key)) {
+ continue;
+ }
+ classList.remove("mapillaryjs-popup-float-" + key);
+ }
+ classList.add("mapillaryjs-popup-float-" + float);
+ this._container.style.transform = floatTranslate[float] + " translate(" + pointPixel[0] + "px," + pointPixel[1] + "px)";
+ };
+ Popup.prototype._rectToPixel = function (rect, position, appliedPosition, renderCamera, size, transform) {
+ if (!position) {
+ var width = this._container.offsetWidth;
+ var height = this._container.offsetHeight;
+ var floatOffsets = {
+ "bottom": [0, height / 2],
+ "bottom-left": [-width / 2, height / 2],
+ "bottom-right": [width / 2, height / 2],
+ "left": [-width / 2, 0],
+ "right": [width / 2, 0],
+ "top": [0, -height / 2],
+ "top-left": [-width / 2, -height / 2],
+ "top-right": [width / 2, -height / 2],
+ };
+ var automaticPositions = ["top", "bottom", "left", "right"];
+ var largestVisibleArea = [0, null, null];
+ for (var _i = 0, automaticPositions_1 = automaticPositions; _i < automaticPositions_1.length; _i++) {
+ var automaticPosition = automaticPositions_1[_i];
+ var autoPointBasic = this._pointFromRectPosition(rect, automaticPosition);
+ var autoPointPixel = this._viewportCoords.basicToCanvasSafe(autoPointBasic[0], autoPointBasic[1], { offsetHeight: size.height, offsetWidth: size.width }, transform, renderCamera.perspective);
+ if (autoPointPixel == null) {
+ continue;
+ }
+ var floatOffset = floatOffsets[automaticPosition];
+ var offsetedPosition = [autoPointPixel[0] + floatOffset[0], autoPointPixel[1] + floatOffset[1]];
+ var staticCoeff = appliedPosition != null && appliedPosition === automaticPosition ? 1 : 0.7;
+ var floats = this._pixelToFloats(offsetedPosition, size, width / staticCoeff, height / (2 * staticCoeff));
+ if (floats.length === 0 &&
+ autoPointPixel[0] > 0 &&
+ autoPointPixel[0] < size.width &&
+ autoPointPixel[1] > 0 &&
+ autoPointPixel[1] < size.height) {
+ return [autoPointPixel, automaticPosition];
+ }
+ var minX = Math.max(offsetedPosition[0] - width / 2, 0);
+ var maxX = Math.min(offsetedPosition[0] + width / 2, size.width);
+ var minY = Math.max(offsetedPosition[1] - height / 2, 0);
+ var maxY = Math.min(offsetedPosition[1] + height / 2, size.height);
+ var visibleX = Math.max(0, maxX - minX);
+ var visibleY = Math.max(0, maxY - minY);
+ var visibleArea = staticCoeff * visibleX * visibleY;
+ if (visibleArea > largestVisibleArea[0]) {
+ largestVisibleArea[0] = visibleArea;
+ largestVisibleArea[1] = autoPointPixel;
+ largestVisibleArea[2] = automaticPosition;
+ }
+ }
+ if (largestVisibleArea[0] > 0) {
+ return [largestVisibleArea[1], largestVisibleArea[2]];
+ }
+ }
+ var pointBasic = this._pointFromRectPosition(rect, position);
+ var pointPixel = this._viewportCoords.basicToCanvasSafe(pointBasic[0], pointBasic[1], { offsetHeight: size.height, offsetWidth: size.width }, transform, renderCamera.perspective);
+ return [pointPixel, position != null ? position : "top"];
+ };
+ Popup.prototype._alignmentToPopupAligment = function (float) {
+ switch (float) {
+ case Viewer_1.Alignment.Bottom:
+ return "bottom";
+ case Viewer_1.Alignment.BottomLeft:
+ return "bottom-left";
+ case Viewer_1.Alignment.BottomRight:
+ return "bottom-right";
+ case Viewer_1.Alignment.Center:
+ return "center";
+ case Viewer_1.Alignment.Left:
+ return "left";
+ case Viewer_1.Alignment.Right:
+ return "right";
+ case Viewer_1.Alignment.Top:
+ return "top";
+ case Viewer_1.Alignment.TopLeft:
+ return "top-left";
+ case Viewer_1.Alignment.TopRight:
+ return "top-right";
+ default:
+ return null;
+ }
+ };
+ Popup.prototype._normalizeOffset = function (offset) {
+ if (offset == null) {
+ return this._normalizeOffset(0);
+ }
+ if (typeof offset === "number") {
+ // input specifies a radius
+ var sideOffset = offset;
+ var sign = sideOffset >= 0 ? 1 : -1;
+ var cornerOffset = sign * Math.round(Math.sqrt(0.5 * Math.pow(sideOffset, 2)));
+ return {
+ "bottom": [0, sideOffset],
+ "bottom-left": [-cornerOffset, cornerOffset],
+ "bottom-right": [cornerOffset, cornerOffset],
+ "center": [0, 0],
+ "left": [-sideOffset, 0],
+ "right": [sideOffset, 0],
+ "top": [0, -sideOffset],
+ "top-left": [-cornerOffset, -cornerOffset],
+ "top-right": [cornerOffset, -cornerOffset],
+ };
+ }
+ else {
+ // input specifes a value for each position
+ return {
+ "bottom": offset.bottom || [0, 0],
+ "bottom-left": offset.bottomLeft || [0, 0],
+ "bottom-right": offset.bottomRight || [0, 0],
+ "center": offset.center || [0, 0],
+ "left": offset.left || [0, 0],
+ "right": offset.right || [0, 0],
+ "top": offset.top || [0, 0],
+ "top-left": offset.topLeft || [0, 0],
+ "top-right": offset.topRight || [0, 0],
+ };
+ }
+ };
+ Popup.prototype._pixelToFloats = function (pointPixel, size, width, height) {
+ var floats = [];
+ if (pointPixel[1] < height) {
+ floats.push("bottom");
+ }
+ else if (pointPixel[1] > size.height - height) {
+ floats.push("top");
+ }
+ if (pointPixel[0] < width / 2) {
+ floats.push("right");
+ }
+ else if (pointPixel[0] > size.width - width / 2) {
+ floats.push("left");
+ }
+ return floats;
+ };
+ Popup.prototype._pointFromRectPosition = function (rect, position) {
+ var x0 = rect[0];
+ var x1 = rect[0] < rect[2] ? rect[2] : rect[2] + 1;
+ var y0 = rect[1];
+ var y1 = rect[3];
+ switch (position) {
+ case "bottom":
+ return [(x0 + x1) / 2, y1];
+ case "bottom-left":
+ return [x0, y1];
+ case "bottom-right":
+ return [x1, y1];
+ case "center":
+ return [(x0 + x1) / 2, (y0 + y1) / 2];
+ case "left":
+ return [x0, (y0 + y1) / 2];
+ case "right":
+ return [x1, (y0 + y1) / 2];
+ case "top":
+ return [(x0 + x1) / 2, y0];
+ case "top-left":
+ return [x0, y0];
+ case "top-right":
+ return [x1, y0];
+ default:
+ return [(x0 + x1) / 2, y1];
+ }
+ };
+ return Popup;
+}());
+exports.Popup = Popup;
+exports.default = Popup;
+
+
+},{"../../../Geo":278,"../../../Utils":285,"../../../Viewer":286,"rxjs":27}],333:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+var Edge_1 = require("../../Edge");
+var Graph_1 = require("../../Graph");
+/**
+ * @class SequenceComponent
+ * @classdesc Component showing navigation arrows for sequence directions
+ * as well as playing button. Exposes an API to start and stop play.
+ */
+var SequenceComponent = /** @class */ (function (_super) {
+ __extends(SequenceComponent, _super);
+ function SequenceComponent(name, container, navigator, renderer, scheduler) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._sequenceDOMRenderer = !!renderer ? renderer : new Component_1.SequenceDOMRenderer(container);
+ _this._scheduler = scheduler;
+ _this._containerWidth$ = new rxjs_1.Subject();
+ _this._hoveredKeySubject$ = new rxjs_1.Subject();
+ _this._hoveredKey$ = _this._hoveredKeySubject$.pipe(operators_1.share());
+ _this._navigator.playService.playing$.pipe(operators_1.skip(1), operators_1.withLatestFrom(_this._configuration$))
+ .subscribe(function (_a) {
+ var playing = _a[0], configuration = _a[1];
+ _this.fire(SequenceComponent.playingchanged, playing);
+ if (playing === configuration.playing) {
+ return;
+ }
+ if (playing) {
+ _this.play();
+ }
+ else {
+ _this.stop();
+ }
+ });
+ _this._navigator.playService.direction$.pipe(operators_1.skip(1), operators_1.withLatestFrom(_this._configuration$))
+ .subscribe(function (_a) {
+ var direction = _a[0], configuration = _a[1];
+ if (direction !== configuration.direction) {
+ _this.setDirection(direction);
+ }
+ });
+ return _this;
+ }
+ Object.defineProperty(SequenceComponent.prototype, "hoveredKey$", {
+ /**
+ * Get hovered key observable.
+ *
+ * @description An observable emitting the key of the node for the direction
+ * arrow that is being hovered. When the mouse leaves a direction arrow null
+ * is emitted.
+ *
+ * @returns {Observable<string>}
+ */
+ get: function () {
+ return this._hoveredKey$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Start playing.
+ *
+ * @fires PlayerComponent#playingchanged
+ */
+ SequenceComponent.prototype.play = function () {
+ this.configure({ playing: true });
+ };
+ /**
+ * Stop playing.
+ *
+ * @fires PlayerComponent#playingchanged
+ */
+ SequenceComponent.prototype.stop = function () {
+ this.configure({ playing: false });
+ };
+ /**
+ * Set the direction to follow when playing.
+ *
+ * @param {EdgeDirection} direction - The direction that will be followed when playing.
+ */
+ SequenceComponent.prototype.setDirection = function (direction) {
+ this.configure({ direction: direction });
+ };
+ /**
+ * Set highlight key.
+ *
+ * @description The arrow pointing towards the node corresponding to the
+ * highlight key will be highlighted.
+ *
+ * @param {string} highlightKey Key of node to be highlighted if existing.
+ */
+ SequenceComponent.prototype.setHighlightKey = function (highlightKey) {
+ this.configure({ highlightKey: highlightKey });
+ };
+ /**
+ * Set max width of container element.
+ *
+ * @description Set max width of the container element holding
+ * the sequence navigation elements. If the min width is larger than the
+ * max width the min width value will be used.
+ *
+ * The container element is automatically resized when the resize
+ * method on the Viewer class is called.
+ *
+ * @param {number} minWidth
+ */
+ SequenceComponent.prototype.setMaxWidth = function (maxWidth) {
+ this.configure({ maxWidth: maxWidth });
+ };
+ /**
+ * Set min width of container element.
+ *
+ * @description Set min width of the container element holding
+ * the sequence navigation elements. If the min width is larger than the
+ * max width the min width value will be used.
+ *
+ * The container element is automatically resized when the resize
+ * method on the Viewer class is called.
+ *
+ * @param {number} minWidth
+ */
+ SequenceComponent.prototype.setMinWidth = function (minWidth) {
+ this.configure({ minWidth: minWidth });
+ };
+ /**
+ * Set the value indicating whether the sequence UI elements should be visible.
+ *
+ * @param {boolean} visible
+ */
+ SequenceComponent.prototype.setVisible = function (visible) {
+ this.configure({ visible: visible });
+ };
+ SequenceComponent.prototype._activate = function () {
+ var _this = this;
+ this._sequenceDOMRenderer.activate();
+ var edgeStatus$ = this._navigator.stateService.currentNode$.pipe(operators_1.switchMap(function (node) {
+ return node.sequenceEdges$;
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ var sequence$ = this._navigator.stateService.currentNode$.pipe(operators_1.distinctUntilChanged(undefined, function (node) {
+ return node.sequenceKey;
+ }), operators_1.switchMap(function (node) {
+ return rxjs_1.concat(rxjs_1.of(null), _this._navigator.graphService.cacheSequence$(node.sequenceKey).pipe(operators_1.retry(3), operators_1.catchError(function (e) {
+ console.error("Failed to cache sequence", e);
+ return rxjs_1.of(null);
+ })));
+ }), operators_1.startWith(null), operators_1.publishReplay(1), operators_1.refCount());
+ this._sequenceSubscription = sequence$.subscribe();
+ var rendererKey$ = this._sequenceDOMRenderer.index$.pipe(operators_1.withLatestFrom(sequence$), operators_1.map(function (_a) {
+ var index = _a[0], sequence = _a[1];
+ return sequence != null ? sequence.keys[index] : null;
+ }), operators_1.filter(function (key) {
+ return !!key;
+ }), operators_1.distinctUntilChanged(), operators_1.publish(), operators_1.refCount());
+ this._moveSubscription = rxjs_1.merge(rendererKey$.pipe(operators_1.debounceTime(100, this._scheduler)), rendererKey$.pipe(operators_1.auditTime(400, this._scheduler))).pipe(operators_1.distinctUntilChanged(), operators_1.switchMap(function (key) {
+ return _this._navigator.moveToKey$(key).pipe(operators_1.catchError(function (e) {
+ return rxjs_1.empty();
+ }));
+ }))
+ .subscribe();
+ this._setSequenceGraphModeSubscription = this._sequenceDOMRenderer.changingPositionChanged$.pipe(operators_1.filter(function (changing) {
+ return changing;
+ }))
+ .subscribe(function () {
+ _this._navigator.graphService.setGraphMode(Graph_1.GraphMode.Sequence);
+ });
+ this._setSpatialGraphModeSubscription = this._sequenceDOMRenderer.changingPositionChanged$.pipe(operators_1.filter(function (changing) {
+ return !changing;
+ }))
+ .subscribe(function () {
+ _this._navigator.graphService.setGraphMode(Graph_1.GraphMode.Spatial);
+ });
+ this._navigator.graphService.graphMode$.pipe(operators_1.switchMap(function (mode) {
+ return mode === Graph_1.GraphMode.Spatial ?
+ _this._navigator.stateService.currentNode$.pipe(operators_1.take(2)) :
+ rxjs_1.empty();
+ }), operators_1.filter(function (node) {
+ return !node.spatialEdges.cached;
+ }), operators_1.switchMap(function (node) {
+ return _this._navigator.graphService.cacheNode$(node.key).pipe(operators_1.catchError(function (e) {
+ return rxjs_1.empty();
+ }));
+ }))
+ .subscribe();
+ this._stopSubscription = this._sequenceDOMRenderer.changingPositionChanged$.pipe(operators_1.filter(function (changing) {
+ return changing;
+ }))
+ .subscribe(function () {
+ _this._navigator.playService.stop();
+ });
+ this._cacheSequenceNodesSubscription = rxjs_1.combineLatest(this._navigator.graphService.graphMode$, this._sequenceDOMRenderer.changingPositionChanged$.pipe(operators_1.startWith(false), operators_1.distinctUntilChanged())).pipe(operators_1.withLatestFrom(this._navigator.stateService.currentNode$), operators_1.switchMap(function (_a) {
+ var _b = _a[0], mode = _b[0], changing = _b[1], node = _a[1];
+ return changing && mode === Graph_1.GraphMode.Sequence ?
+ _this._navigator.graphService.cacheSequenceNodes$(node.sequenceKey, node.key).pipe(operators_1.retry(3), operators_1.catchError(function (error) {
+ console.error("Failed to cache sequence nodes.", error);
+ return rxjs_1.empty();
+ })) :
+ rxjs_1.empty();
+ }))
+ .subscribe();
+ var position$ = sequence$.pipe(operators_1.switchMap(function (sequence) {
+ if (!sequence) {
+ return rxjs_1.of({ index: null, max: null });
+ }
+ var firstCurrentKey = true;
+ return _this._sequenceDOMRenderer.changingPositionChanged$.pipe(operators_1.startWith(false), operators_1.distinctUntilChanged(), operators_1.switchMap(function (changingPosition) {
+ var skipCount = !changingPosition && firstCurrentKey ? 0 : 1;
+ firstCurrentKey = false;
+ return changingPosition ?
+ rendererKey$ :
+ _this._navigator.stateService.currentNode$.pipe(operators_1.map(function (node) {
+ return node.key;
+ }), operators_1.distinctUntilChanged(), operators_1.skip(skipCount));
+ }), operators_1.map(function (key) {
+ var index = sequence.keys.indexOf(key);
+ if (index === -1) {
+ return { index: null, max: null };
+ }
+ return { index: index, max: sequence.keys.length - 1 };
+ }));
+ }));
+ this._renderSubscription = rxjs_1.combineLatest(edgeStatus$, this._configuration$, this._containerWidth$, this._sequenceDOMRenderer.changed$.pipe(operators_1.startWith(this._sequenceDOMRenderer)), this._navigator.playService.speed$, position$).pipe(operators_1.map(function (_a) {
+ var edgeStatus = _a[0], configuration = _a[1], containerWidth = _a[2], renderer = _a[3], speed = _a[4], position = _a[5];
+ var vNode = _this._sequenceDOMRenderer
+ .render(edgeStatus, configuration, containerWidth, speed, position.index, position.max, _this, _this._navigator);
+ return { name: _this._name, vnode: vNode };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ this._setSpeedSubscription = this._sequenceDOMRenderer.speed$
+ .subscribe(function (speed) {
+ _this._navigator.playService.setSpeed(speed);
+ });
+ this._setDirectionSubscription = this._configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.direction;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (direction) {
+ _this._navigator.playService.setDirection(direction);
+ });
+ this._containerWidthSubscription = rxjs_1.combineLatest(this._container.renderService.size$, this._configuration$.pipe(operators_1.distinctUntilChanged(function (value1, value2) {
+ return value1[0] === value2[0] && value1[1] === value2[1];
+ }, function (configuration) {
+ return [configuration.minWidth, configuration.maxWidth];
+ }))).pipe(operators_1.map(function (_a) {
+ var size = _a[0], configuration = _a[1];
+ return _this._sequenceDOMRenderer.getContainerWidth(size, configuration);
+ }))
+ .subscribe(this._containerWidth$);
+ this._playingSubscription = this._configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.playing;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (playing) {
+ if (playing) {
+ _this._navigator.playService.play();
+ }
+ else {
+ _this._navigator.playService.stop();
+ }
+ });
+ this._hoveredKeySubscription = this._sequenceDOMRenderer.mouseEnterDirection$.pipe(operators_1.switchMap(function (direction) {
+ var edgeTo$ = edgeStatus$.pipe(operators_1.map(function (edgeStatus) {
+ for (var _i = 0, _a = edgeStatus.edges; _i < _a.length; _i++) {
+ var edge = _a[_i];
+ if (edge.data.direction === direction) {
+ return edge.to;
+ }
+ }
+ return null;
+ }), operators_1.takeUntil(_this._sequenceDOMRenderer.mouseLeaveDirection$));
+ return rxjs_1.concat(edgeTo$, rxjs_1.of(null));
+ }), operators_1.distinctUntilChanged())
+ .subscribe(this._hoveredKeySubject$);
+ this._emitHoveredKeySubscription = this._hoveredKey$
+ .subscribe(function (key) {
+ _this.fire(SequenceComponent.hoveredkeychanged, key);
+ });
+ };
+ SequenceComponent.prototype._deactivate = function () {
+ this._emitHoveredKeySubscription.unsubscribe();
+ this._renderSubscription.unsubscribe();
+ this._playingSubscription.unsubscribe();
+ this._containerWidthSubscription.unsubscribe();
+ this._hoveredKeySubscription.unsubscribe();
+ this._setSpeedSubscription.unsubscribe();
+ this._setDirectionSubscription.unsubscribe();
+ this._setSequenceGraphModeSubscription.unsubscribe();
+ this._setSpatialGraphModeSubscription.unsubscribe();
+ this._sequenceSubscription.unsubscribe();
+ this._moveSubscription.unsubscribe();
+ this._cacheSequenceNodesSubscription.unsubscribe();
+ this._stopSubscription.unsubscribe();
+ this._sequenceDOMRenderer.deactivate();
+ };
+ SequenceComponent.prototype._getDefaultConfiguration = function () {
+ return {
+ direction: Edge_1.EdgeDirection.Next,
+ maxWidth: 108,
+ minWidth: 70,
+ playing: false,
+ visible: true,
+ };
+ };
+ /** @inheritdoc */
+ SequenceComponent.componentName = "sequence";
+ /**
+ * Event fired when playing starts or stops.
+ *
+ * @event SequenceComponent#playingchanged
+ * @type {boolean} Indicates whether the player is playing.
+ */
+ SequenceComponent.playingchanged = "playingchanged";
+ /**
+ * Event fired when the hovered key changes.
+ *
+ * @description Emits the key of the node for the direction
+ * arrow that is being hovered. When the mouse leaves a
+ * direction arrow null is emitted.
+ *
+ * @event SequenceComponent#hoveredkeychanged
+ * @type {string} The hovered key, null if no key is hovered.
+ */
+ SequenceComponent.hoveredkeychanged = "hoveredkeychanged";
+ return SequenceComponent;
+}(Component_1.Component));
+exports.SequenceComponent = SequenceComponent;
+Component_1.ComponentService.register(SequenceComponent);
+exports.default = SequenceComponent;
+
+},{"../../Component":275,"../../Edge":276,"../../Graph":279,"rxjs":27,"rxjs/operators":225}],334:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var Component_1 = require("../../Component");
+var Edge_1 = require("../../Edge");
+var Error_1 = require("../../Error");
+var SequenceDOMRenderer = /** @class */ (function () {
+ function SequenceDOMRenderer(container) {
+ this._container = container;
+ this._minThresholdWidth = 320;
+ this._maxThresholdWidth = 1480;
+ this._minThresholdHeight = 240;
+ this._maxThresholdHeight = 820;
+ this._stepperDefaultWidth = 108;
+ this._controlsDefaultWidth = 88;
+ this._defaultHeight = 30;
+ this._expandControls = false;
+ this._mode = Component_1.SequenceMode.Default;
+ this._speed = 0.5;
+ this._changingSpeed = false;
+ this._index = null;
+ this._changingPosition = false;
+ this._mouseEnterDirection$ = new rxjs_1.Subject();
+ this._mouseLeaveDirection$ = new rxjs_1.Subject();
+ this._notifyChanged$ = new rxjs_1.Subject();
+ this._notifyChangingPositionChanged$ = new rxjs_1.Subject();
+ this._notifySpeedChanged$ = new rxjs_1.Subject();
+ this._notifyIndexChanged$ = new rxjs_1.Subject();
+ }
+ Object.defineProperty(SequenceDOMRenderer.prototype, "changed$", {
+ get: function () {
+ return this._notifyChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SequenceDOMRenderer.prototype, "changingPositionChanged$", {
+ get: function () {
+ return this._notifyChangingPositionChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SequenceDOMRenderer.prototype, "speed$", {
+ get: function () {
+ return this._notifySpeedChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SequenceDOMRenderer.prototype, "index$", {
+ get: function () {
+ return this._notifyIndexChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SequenceDOMRenderer.prototype, "mouseEnterDirection$", {
+ get: function () {
+ return this._mouseEnterDirection$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SequenceDOMRenderer.prototype, "mouseLeaveDirection$", {
+ get: function () {
+ return this._mouseLeaveDirection$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ SequenceDOMRenderer.prototype.activate = function () {
+ var _this = this;
+ if (!!this._changingSubscription) {
+ return;
+ }
+ this._changingSubscription = rxjs_1.merge(this._container.mouseService.documentMouseUp$, this._container.touchService.touchEnd$.pipe(operators_1.filter(function (touchEvent) {
+ return touchEvent.touches.length === 0;
+ })))
+ .subscribe(function (event) {
+ if (_this._changingSpeed) {
+ _this._changingSpeed = false;
+ }
+ if (_this._changingPosition) {
+ _this._setChangingPosition(false);
+ }
+ });
+ };
+ SequenceDOMRenderer.prototype.deactivate = function () {
+ if (!this._changingSubscription) {
+ return;
+ }
+ this._changingSpeed = false;
+ this._changingPosition = false;
+ this._expandControls = false;
+ this._mode = Component_1.SequenceMode.Default;
+ this._changingSubscription.unsubscribe();
+ this._changingSubscription = null;
+ };
+ SequenceDOMRenderer.prototype.render = function (edgeStatus, configuration, containerWidth, speed, index, max, component, navigator) {
+ if (configuration.visible === false) {
+ return vd.h("div.SequenceContainer", {}, []);
+ }
+ var stepper = this._createStepper(edgeStatus, configuration, containerWidth, component, navigator);
+ var controls = this._createSequenceControls(containerWidth);
+ var playback = this._createPlaybackControls(containerWidth, speed, component, configuration);
+ var timeline = this._createTimelineControls(containerWidth, index, max);
+ return vd.h("div.SequenceContainer", [stepper, controls, playback, timeline]);
+ };
+ SequenceDOMRenderer.prototype.getContainerWidth = function (size, configuration) {
+ var minWidth = configuration.minWidth;
+ var maxWidth = configuration.maxWidth;
+ if (maxWidth < minWidth) {
+ maxWidth = minWidth;
+ }
+ var relativeWidth = (size.width - this._minThresholdWidth) / (this._maxThresholdWidth - this._minThresholdWidth);
+ var relativeHeight = (size.height - this._minThresholdHeight) / (this._maxThresholdHeight - this._minThresholdHeight);
+ var coeff = Math.max(0, Math.min(1, Math.min(relativeWidth, relativeHeight)));
+ return minWidth + coeff * (maxWidth - minWidth);
+ };
+ SequenceDOMRenderer.prototype._createPositionInput = function (index, max) {
+ var _this = this;
+ this._index = index;
+ var onPosition = function (e) {
+ _this._index = Number(e.target.value);
+ _this._notifyIndexChanged$.next(_this._index);
+ };
+ var boundingRect = this._container.domContainer.getBoundingClientRect();
+ var width = Math.max(276, Math.min(410, 5 + 0.8 * boundingRect.width)) - 65;
+ var onStart = function (e) {
+ e.stopPropagation();
+ _this._setChangingPosition(true);
+ };
+ var onMove = function (e) {
+ if (_this._changingPosition === true) {
+ e.stopPropagation();
+ }
+ };
+ var onKeyDown = function (e) {
+ if (e.key === "ArrowDown" || e.key === "ArrowLeft" ||
+ e.key === "ArrowRight" || e.key === "ArrowUp") {
+ e.preventDefault();
+ }
+ };
+ var positionInputProperties = {
+ max: max != null ? max : 1,
+ min: 0,
+ onchange: onPosition,
+ oninput: onPosition,
+ onkeydown: onKeyDown,
+ onmousedown: onStart,
+ onmousemove: onMove,
+ ontouchmove: onMove,
+ ontouchstart: onStart,
+ style: {
+ width: width + "px",
+ },
+ type: "range",
+ value: index != null ? index : 0,
+ };
+ var disabled = index == null || max == null || max <= 1;
+ if (disabled) {
+ positionInputProperties.disabled = "true";
+ }
+ var positionInput = vd.h("input.SequencePosition", positionInputProperties, []);
+ var positionContainerClass = disabled ? ".SequencePositionContainerDisabled" : ".SequencePositionContainer";
+ return vd.h("div" + positionContainerClass, [positionInput]);
+ };
+ SequenceDOMRenderer.prototype._createSpeedInput = function (speed) {
+ var _this = this;
+ this._speed = speed;
+ var onSpeed = function (e) {
+ _this._speed = Number(e.target.value) / 1000;
+ _this._notifySpeedChanged$.next(_this._speed);
+ };
+ var boundingRect = this._container.domContainer.getBoundingClientRect();
+ var width = Math.max(276, Math.min(410, 5 + 0.8 * boundingRect.width)) - 160;
+ var onStart = function (e) {
+ _this._changingSpeed = true;
+ e.stopPropagation();
+ };
+ var onMove = function (e) {
+ if (_this._changingSpeed === true) {
+ e.stopPropagation();
+ }
+ };
+ var onKeyDown = function (e) {
+ if (e.key === "ArrowDown" || e.key === "ArrowLeft" ||
+ e.key === "ArrowRight" || e.key === "ArrowUp") {
+ e.preventDefault();
+ }
+ };
+ var speedInput = vd.h("input.SequenceSpeed", {
+ max: 1000,
+ min: 0,
+ onchange: onSpeed,
+ oninput: onSpeed,
+ onkeydown: onKeyDown,
+ onmousedown: onStart,
+ onmousemove: onMove,
+ ontouchmove: onMove,
+ ontouchstart: onStart,
+ style: {
+ width: width + "px",
+ },
+ type: "range",
+ value: 1000 * speed,
+ }, []);
+ return vd.h("div.SequenceSpeedContainer", [speedInput]);
+ };
+ SequenceDOMRenderer.prototype._createPlaybackControls = function (containerWidth, speed, component, configuration) {
+ var _this = this;
+ if (this._mode !== Component_1.SequenceMode.Playback) {
+ return vd.h("div.SequencePlayback", []);
+ }
+ var switchIcon = vd.h("div.SequenceSwitchIcon.SequenceIconVisible", []);
+ var direction = configuration.direction === Edge_1.EdgeDirection.Next ?
+ Edge_1.EdgeDirection.Prev : Edge_1.EdgeDirection.Next;
+ var playing = configuration.playing;
+ var switchButtonProperties = {
+ onclick: function () {
+ if (!playing) {
+ component.setDirection(direction);
+ }
+ },
+ };
+ var switchButtonClassName = configuration.playing ? ".SequenceSwitchButtonDisabled" : ".SequenceSwitchButton";
+ var switchButton = vd.h("div" + switchButtonClassName, switchButtonProperties, [switchIcon]);
+ var slowIcon = vd.h("div.SequenceSlowIcon.SequenceIconVisible", []);
+ var slowContainer = vd.h("div.SequenceSlowContainer", [slowIcon]);
+ var fastIcon = vd.h("div.SequenceFastIcon.SequenceIconVisible", []);
+ var fastContainer = vd.h("div.SequenceFastContainer", [fastIcon]);
+ var closeIcon = vd.h("div.SequenceCloseIcon.SequenceIconVisible", []);
+ var closeButtonProperties = {
+ onclick: function () {
+ _this._mode = Component_1.SequenceMode.Default;
+ _this._notifyChanged$.next(_this);
+ },
+ };
+ var closeButton = vd.h("div.SequenceCloseButton", closeButtonProperties, [closeIcon]);
+ var speedInput = this._createSpeedInput(speed);
+ var playbackChildren = [switchButton, slowContainer, speedInput, fastContainer, closeButton];
+ var top = Math.round(containerWidth / this._stepperDefaultWidth * this._defaultHeight + 10);
+ var playbackProperties = { style: { top: top + "px" } };
+ return vd.h("div.SequencePlayback", playbackProperties, playbackChildren);
+ };
+ SequenceDOMRenderer.prototype._createPlayingButton = function (nextKey, prevKey, configuration, component) {
+ var canPlay = configuration.direction === Edge_1.EdgeDirection.Next && nextKey != null ||
+ configuration.direction === Edge_1.EdgeDirection.Prev && prevKey != null;
+ var onclick = configuration.playing ?
+ function (e) { component.stop(); } :
+ canPlay ? function (e) { component.play(); } : null;
+ var buttonProperties = { onclick: onclick };
+ var iconClass = configuration.playing ?
+ "Stop" :
+ canPlay ? "Play" : "PlayDisabled";
+ var iconProperties = { className: iconClass };
+ if (configuration.direction === Edge_1.EdgeDirection.Prev) {
+ iconProperties.style = {
+ transform: "rotate(180deg) translate(50%, 50%)",
+ };
+ }
+ var icon = vd.h("div.SequenceComponentIcon", iconProperties, []);
+ var buttonClass = canPlay ? "SequencePlay" : "SequencePlayDisabled";
+ return vd.h("div." + buttonClass, buttonProperties, [icon]);
+ };
+ SequenceDOMRenderer.prototype._createSequenceControls = function (containerWidth) {
+ var _this = this;
+ var borderRadius = Math.round(8 / this._stepperDefaultWidth * containerWidth);
+ var expanderProperties = {
+ onclick: function () {
+ _this._expandControls = !_this._expandControls;
+ _this._mode = Component_1.SequenceMode.Default;
+ _this._notifyChanged$.next(_this);
+ },
+ style: {
+ "border-bottom-right-radius": borderRadius + "px",
+ "border-top-right-radius": borderRadius + "px",
+ },
+ };
+ var expanderBar = vd.h("div.SequenceExpanderBar", []);
+ var expander = vd.h("div.SequenceExpanderButton", expanderProperties, [expanderBar]);
+ var fastIconClassName = this._mode === Component_1.SequenceMode.Playback ?
+ ".SequenceFastIconGrey.SequenceIconVisible" : ".SequenceFastIcon";
+ var fastIcon = vd.h("div" + fastIconClassName, []);
+ var playbackProperties = {
+ onclick: function () {
+ _this._mode = _this._mode === Component_1.SequenceMode.Playback ?
+ Component_1.SequenceMode.Default :
+ Component_1.SequenceMode.Playback;
+ _this._notifyChanged$.next(_this);
+ },
+ };
+ var playback = vd.h("div.SequencePlaybackButton", playbackProperties, [fastIcon]);
+ var timelineIconClassName = this._mode === Component_1.SequenceMode.Timeline ?
+ ".SequenceTimelineIconGrey.SequenceIconVisible" : ".SequenceTimelineIcon";
+ var timelineIcon = vd.h("div" + timelineIconClassName, []);
+ var timelineProperties = {
+ onclick: function () {
+ _this._mode = _this._mode === Component_1.SequenceMode.Timeline ?
+ Component_1.SequenceMode.Default :
+ Component_1.SequenceMode.Timeline;
+ _this._notifyChanged$.next(_this);
+ },
+ };
+ var timeline = vd.h("div.SequenceTimelineButton", timelineProperties, [timelineIcon]);
+ var properties = {
+ style: {
+ height: (this._defaultHeight / this._stepperDefaultWidth * containerWidth) + "px",
+ transform: "translate(" + (containerWidth / 2 + 2) + "px, 0)",
+ width: (this._controlsDefaultWidth / this._stepperDefaultWidth * containerWidth) + "px",
+ },
+ };
+ var className = ".SequenceControls" +
+ (this._expandControls ? ".SequenceControlsExpanded" : "");
+ return vd.h("div" + className, properties, [playback, timeline, expander]);
+ };
+ SequenceDOMRenderer.prototype._createSequenceArrows = function (nextKey, prevKey, containerWidth, configuration, navigator) {
+ var _this = this;
+ var nextProperties = {
+ onclick: nextKey != null ?
+ function (e) {
+ navigator.moveDir$(Edge_1.EdgeDirection.Next)
+ .subscribe(undefined, function (error) {
+ if (!(error instanceof Error_1.AbortMapillaryError)) {
+ console.error(error);
+ }
+ });
+ } :
+ null,
+ onmouseenter: function (e) { _this._mouseEnterDirection$.next(Edge_1.EdgeDirection.Next); },
+ onmouseleave: function (e) { _this._mouseLeaveDirection$.next(Edge_1.EdgeDirection.Next); },
+ };
+ var borderRadius = Math.round(8 / this._stepperDefaultWidth * containerWidth);
+ var prevProperties = {
+ onclick: prevKey != null ?
+ function (e) {
+ navigator.moveDir$(Edge_1.EdgeDirection.Prev)
+ .subscribe(undefined, function (error) {
+ if (!(error instanceof Error_1.AbortMapillaryError)) {
+ console.error(error);
+ }
+ });
+ } :
+ null,
+ onmouseenter: function (e) { _this._mouseEnterDirection$.next(Edge_1.EdgeDirection.Prev); },
+ onmouseleave: function (e) { _this._mouseLeaveDirection$.next(Edge_1.EdgeDirection.Prev); },
+ style: {
+ "border-bottom-left-radius": borderRadius + "px",
+ "border-top-left-radius": borderRadius + "px",
+ },
+ };
+ var nextClass = this._getStepClassName(Edge_1.EdgeDirection.Next, nextKey, configuration.highlightKey);
+ var prevClass = this._getStepClassName(Edge_1.EdgeDirection.Prev, prevKey, configuration.highlightKey);
+ var nextIcon = vd.h("div.SequenceComponentIcon", []);
+ var prevIcon = vd.h("div.SequenceComponentIcon", []);
+ return [
+ vd.h("div." + prevClass, prevProperties, [prevIcon]),
+ vd.h("div." + nextClass, nextProperties, [nextIcon]),
+ ];
+ };
+ SequenceDOMRenderer.prototype._createStepper = function (edgeStatus, configuration, containerWidth, component, navigator) {
+ var nextKey = null;
+ var prevKey = null;
+ for (var _i = 0, _a = edgeStatus.edges; _i < _a.length; _i++) {
+ var edge = _a[_i];
+ if (edge.data.direction === Edge_1.EdgeDirection.Next) {
+ nextKey = edge.to;
+ }
+ if (edge.data.direction === Edge_1.EdgeDirection.Prev) {
+ prevKey = edge.to;
+ }
+ }
+ var playingButton = this._createPlayingButton(nextKey, prevKey, configuration, component);
+ var buttons = this._createSequenceArrows(nextKey, prevKey, containerWidth, configuration, navigator);
+ buttons.splice(1, 0, playingButton);
+ var containerProperties = {
+ oncontextmenu: function (event) { event.preventDefault(); },
+ style: {
+ height: (this._defaultHeight / this._stepperDefaultWidth * containerWidth) + "px",
+ width: containerWidth + "px",
+ },
+ };
+ return vd.h("div.SequenceStepper", containerProperties, buttons);
+ };
+ SequenceDOMRenderer.prototype._createTimelineControls = function (containerWidth, index, max) {
+ var _this = this;
+ if (this._mode !== Component_1.SequenceMode.Timeline) {
+ return vd.h("div.SequenceTimeline", []);
+ }
+ var positionInput = this._createPositionInput(index, max);
+ var closeIcon = vd.h("div.SequenceCloseIcon.SequenceIconVisible", []);
+ var closeButtonProperties = {
+ onclick: function () {
+ _this._mode = Component_1.SequenceMode.Default;
+ _this._notifyChanged$.next(_this);
+ },
+ };
+ var closeButton = vd.h("div.SequenceCloseButton", closeButtonProperties, [closeIcon]);
+ var top = Math.round(containerWidth / this._stepperDefaultWidth * this._defaultHeight + 10);
+ var playbackProperties = { style: { top: top + "px" } };
+ return vd.h("div.SequenceTimeline", playbackProperties, [positionInput, closeButton]);
+ };
+ SequenceDOMRenderer.prototype._getStepClassName = function (direction, key, highlightKey) {
+ var className = direction === Edge_1.EdgeDirection.Next ?
+ "SequenceStepNext" :
+ "SequenceStepPrev";
+ if (key == null) {
+ className += "Disabled";
+ }
+ else {
+ if (highlightKey === key) {
+ className += "Highlight";
+ }
+ }
+ return className;
+ };
+ SequenceDOMRenderer.prototype._setChangingPosition = function (value) {
+ this._changingPosition = value;
+ this._notifyChangingPositionChanged$.next(value);
+ };
+ return SequenceDOMRenderer;
+}());
+exports.SequenceDOMRenderer = SequenceDOMRenderer;
+exports.default = SequenceDOMRenderer;
+
+},{"../../Component":275,"../../Edge":276,"../../Error":277,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],335:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var SequenceMode;
+(function (SequenceMode) {
+ SequenceMode[SequenceMode["Default"] = 0] = "Default";
+ SequenceMode[SequenceMode["Playback"] = 1] = "Playback";
+ SequenceMode[SequenceMode["Timeline"] = 2] = "Timeline";
+})(SequenceMode = exports.SequenceMode || (exports.SequenceMode = {}));
+exports.default = SequenceMode;
+
+},{}],336:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+
+var path = require("path");
+var Shaders = /** @class */ (function () {
+ function Shaders() {
+ }
+ Shaders.equirectangular = {
+ fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform float phiLength;\nuniform float phiShift;\nuniform float thetaLength;\nuniform float thetaShift;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vec3 b = normalize(vRstq.xyz);\n float lat = -asin(b.y);\n float lon = atan(b.x, b.z);\n float x = (lon - phiShift) / phiLength + 0.5;\n float y = (lat - thetaShift) / thetaLength + 0.5;\n vec4 baseColor = texture2D(projectorTex, vec2(x, y));\n baseColor.a = opacity;\n gl_FragColor = baseColor;\n}",
+ vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vRstq = projectorMat * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+ };
+ Shaders.equirectangularCurtain = {
+ fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float curtain;\nuniform float opacity;\nuniform float phiLength;\nuniform float phiShift;\nuniform float thetaLength;\nuniform float thetaShift;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vec3 b = normalize(vRstq.xyz);\n float lat = -asin(b.y);\n float lon = atan(b.x, b.z);\n float x = (lon - phiShift) / phiLength + 0.5;\n float y = (lat - thetaShift) / thetaLength + 0.5;\n\n bool inverted = curtain < 0.5;\n\n float curtainMin = inverted ? curtain + 0.5 : curtain - 0.5;\n float curtainMax = curtain;\n\n bool insideCurtain = inverted ?\n x > curtainMin || x < curtainMax :\n x > curtainMin && x < curtainMax;\n\n vec4 baseColor;\n if (insideCurtain) {\n baseColor = texture2D(projectorTex, vec2(x, y));\n baseColor.a = opacity;\n } else {\n baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n\n gl_FragColor = baseColor;\n}",
+ vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vRstq = projectorMat * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+ };
+ Shaders.perspective = {
+ fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform float focal;\nuniform float k1;\nuniform float k2;\nuniform float scale_x;\nuniform float scale_y;\nuniform float radial_peak;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n float x = vRstq.x / vRstq.z;\n float y = vRstq.y / vRstq.z;\n float r2 = x * x + y * y;\n\n if (radial_peak > 0. && r2 > radial_peak * sqrt(r2)) {\n r2 = radial_peak * radial_peak;\n }\n\n float d = 1.0 + k1 * r2 + k2 * r2 * r2;\n float u = scale_x * focal * d * x + 0.5;\n float v = - scale_y * focal * d * y + 0.5;\n\n vec4 baseColor;\n if (u >= 0. && u <= 1. && v >= 0. && v <= 1.) {\n baseColor = texture2D(projectorTex, vec2(u, v));\n baseColor.a = opacity;\n } else {\n baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n\n gl_FragColor = baseColor;\n}",
+ vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vRstq = projectorMat * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+ };
+ Shaders.perspectiveCurtain = {
+ fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform float focal;\nuniform float k1;\nuniform float k2;\nuniform float scale_x;\nuniform float scale_y;\nuniform float radial_peak;\nuniform float curtain;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n float x = vRstq.x / vRstq.z;\n float y = vRstq.y / vRstq.z;\n float r2 = x * x + y * y;\n\n if (radial_peak > 0. && r2 > radial_peak * sqrt(r2)) {\n r2 = radial_peak * radial_peak;\n }\n\n float d = 1.0 + k1 * r2 + k2 * r2 * r2;\n float u = scale_x * focal * d * x + 0.5;\n float v = - scale_y * focal * d * y + 0.5;\n\n vec4 baseColor;\n if ((u < curtain || curtain >= 1.0) && u >= 0. && u <= 1. && v >= 0. && v <= 1.) {\n baseColor = texture2D(projectorTex, vec2(u, v));\n baseColor.a = opacity;\n } else {\n baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n\n gl_FragColor = baseColor;\n}\n",
+ vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vRstq = projectorMat * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+ };
+ Shaders.fisheye = {
+ fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform float focal;\nuniform float k1;\nuniform float k2;\nuniform float scale_x;\nuniform float scale_y;\nuniform float radial_peak;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n float x = vRstq.x;\n float y = vRstq.y;\n float z = vRstq.z;\n\n float r = sqrt(x * x + y * y);\n float theta = atan(r, z);\n\n if (radial_peak > 0. && theta > radial_peak) {\n theta = radial_peak;\n }\n\n float theta2 = theta * theta;\n float theta_d = theta * (1.0 + theta2 * (k1 + theta2 * k2));\n float s = focal * theta_d / r;\n\n float u = scale_x * s * x + 0.5;\n float v = -scale_y * s * y + 0.5;\n\n vec4 baseColor;\n if (u >= 0. && u <= 1. && v >= 0. && v <= 1.) {\n baseColor = texture2D(projectorTex, vec2(u, v));\n baseColor.a = opacity;\n } else {\n baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n\n gl_FragColor = baseColor;\n}\n",
+ vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vRstq = projectorMat * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+ };
+ Shaders.fisheyeCurtain = {
+ fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform float focal;\nuniform float k1;\nuniform float k2;\nuniform float scale_x;\nuniform float scale_y;\nuniform float radial_peak;\nuniform float curtain;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n float x = vRstq.x;\n float y = vRstq.y;\n float z = vRstq.z;\n\n float r2 = sqrt(x * x + y * y);\n float theta = atan(r2, z);\n\n if (radial_peak > 0. && theta > radial_peak) {\n theta = radial_peak;\n }\n\n float theta2 = theta * theta;\n float theta_d = theta * (1.0 + theta2 * (k1 + theta2 * k2));\n float s = focal * theta_d / r2;\n\n float u = scale_x * s * x + 0.5;\n float v = -scale_y * s * y + 0.5;\n\n vec4 baseColor;\n if ((u < curtain || curtain >= 1.0) && u >= 0. && u <= 1. && v >= 0. && v <= 1.) {\n baseColor = texture2D(projectorTex, vec2(u, v));\n baseColor.a = opacity;\n } else {\n baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n\n gl_FragColor = baseColor;\n}\n",
+ vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vRstq = projectorMat * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+ };
+ Shaders.perspectiveDistorted = {
+ fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n float u = vRstq.x / vRstq.w;\n float v = vRstq.y / vRstq.w;\n\n vec4 baseColor;\n if (u >= 0. && u <= 1. && v >= 0. && v <= 1.) {\n baseColor = texture2D(projectorTex, vec2(u, v));\n baseColor.a = opacity;\n } else {\n baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n\n gl_FragColor = baseColor;\n}\n",
+ vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vRstq = projectorMat * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n",
+ };
+ Shaders.perspectiveDistortedCurtain = {
+ fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform float curtain;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n float u = vRstq.x / vRstq.w;\n float v = vRstq.y / vRstq.w;\n\n vec4 baseColor;\n if ((u < curtain || curtain >= 1.0) && u >= 0. && u <= 1. && v >= 0. && v <= 1.) {\n baseColor = texture2D(projectorTex, vec2(u, v));\n baseColor.a = opacity;\n } else {\n baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n\n gl_FragColor = baseColor;\n}\n",
+ vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n vRstq = projectorMat * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n",
+ };
+ return Shaders;
+}());
+exports.Shaders = Shaders;
+
+
+},{"path":23}],337:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+var Geo_1 = require("../../Geo");
+var State_1 = require("../../State");
+var Render_1 = require("../../Render");
+var Tiles_1 = require("../../Tiles");
+var Utils_1 = require("../../Utils");
+/**
+ * @class SliderComponent
+ *
+ * @classdesc Component for comparing pairs of images. Renders
+ * a slider for adjusting the curtain of the first image.
+ *
+ * Deactivate the sequence, direction and image plane
+ * components when activating the slider component to avoid
+ * interfering UI elements.
+ *
+ * To retrive and use the slider component
+ *
+ * @example
+ * ```
+ * var viewer = new Mapillary.Viewer(
+ * "<element-id>",
+ * "<client-id>",
+ * "<my key>");
+ *
+ * viewer.deactivateComponent("imagePlane");
+ * viewer.deactivateComponent("direction");
+ * viewer.deactivateComponent("sequence");
+ *
+ * viewer.activateComponent("slider");
+ *
+ * var sliderComponent = viewer.getComponent("slider");
+ * ```
+ */
+var SliderComponent = /** @class */ (function (_super) {
+ __extends(SliderComponent, _super);
+ /** @ignore */
+ function SliderComponent(name, container, navigator, viewportCoords) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._viewportCoords = !!viewportCoords ? viewportCoords : new Geo_1.ViewportCoords();
+ _this._domRenderer = new Component_1.SliderDOMRenderer(container);
+ _this._imageTileLoader = new Tiles_1.ImageTileLoader(Utils_1.Urls.tileScheme, Utils_1.Urls.tileDomain, Utils_1.Urls.origin);
+ _this._roiCalculator = new Tiles_1.RegionOfInterestCalculator();
+ _this._spatial = new Geo_1.Spatial();
+ _this._glRendererOperation$ = new rxjs_1.Subject();
+ _this._glRendererCreator$ = new rxjs_1.Subject();
+ _this._glRendererDisposer$ = new rxjs_1.Subject();
+ _this._glRenderer$ = _this._glRendererOperation$.pipe(operators_1.scan(function (glRenderer, operation) {
+ return operation(glRenderer);
+ }, null), operators_1.filter(function (glRenderer) {
+ return glRenderer != null;
+ }), operators_1.distinctUntilChanged(undefined, function (glRenderer) {
+ return glRenderer.frameId;
+ }));
+ _this._glRendererCreator$.pipe(operators_1.map(function () {
+ return function (glRenderer) {
+ if (glRenderer != null) {
+ throw new Error("Multiple slider states can not be created at the same time");
+ }
+ return new Component_1.SliderGLRenderer();
+ };
+ }))
+ .subscribe(_this._glRendererOperation$);
+ _this._glRendererDisposer$.pipe(operators_1.map(function () {
+ return function (glRenderer) {
+ glRenderer.dispose();
+ return null;
+ };
+ }))
+ .subscribe(_this._glRendererOperation$);
+ return _this;
+ }
+ /**
+ * Set the initial position.
+ *
+ * @description Configures the intial position of the slider.
+ * The inital position value will be used when the component
+ * is activated.
+ *
+ * @param {number} initialPosition - Initial slider position.
+ */
+ SliderComponent.prototype.setInitialPosition = function (initialPosition) {
+ this.configure({ initialPosition: initialPosition });
+ };
+ /**
+ * Set the image keys.
+ *
+ * @description Configures the component to show the image
+ * planes for the supplied image keys.
+ *
+ * @param {ISliderKeys} keys - Slider keys object specifying
+ * the images to be shown in the foreground and the background.
+ */
+ SliderComponent.prototype.setKeys = function (keys) {
+ this.configure({ keys: keys });
+ };
+ /**
+ * Set the slider mode.
+ *
+ * @description Configures the mode for transitions between
+ * image pairs.
+ *
+ * @param {SliderMode} mode - Slider mode to be set.
+ */
+ SliderComponent.prototype.setSliderMode = function (mode) {
+ this.configure({ mode: mode });
+ };
+ /**
+ * Set the value controlling if the slider is visible.
+ *
+ * @param {boolean} sliderVisible - Value indicating if
+ * the slider should be visible or not.
+ */
+ SliderComponent.prototype.setSliderVisible = function (sliderVisible) {
+ this.configure({ sliderVisible: sliderVisible });
+ };
+ SliderComponent.prototype._activate = function () {
+ var _this = this;
+ this._modeSubcription = this._domRenderer.mode$
+ .subscribe(function (mode) {
+ _this.setSliderMode(mode);
+ });
+ this._glRenderSubscription = this._glRenderer$.pipe(operators_1.map(function (glRenderer) {
+ var renderHash = {
+ name: _this._name,
+ render: {
+ frameId: glRenderer.frameId,
+ needsRender: glRenderer.needsRender,
+ render: glRenderer.render.bind(glRenderer),
+ stage: Render_1.GLRenderStage.Background,
+ },
+ };
+ return renderHash;
+ }))
+ .subscribe(this._container.glRenderer.render$);
+ var position$ = rxjs_1.concat(this.configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.initialPosition != null ?
+ configuration.initialPosition : 1;
+ }), operators_1.first()), this._domRenderer.position$);
+ var mode$ = this.configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.mode;
+ }), operators_1.distinctUntilChanged());
+ var motionless$ = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return frame.state.motionless;
+ }), operators_1.distinctUntilChanged());
+ var fullPano$ = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return frame.state.currentNode.fullPano;
+ }), operators_1.distinctUntilChanged());
+ var sliderVisible$ = rxjs_1.combineLatest(this._configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.sliderVisible;
+ })), this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return !(frame.state.currentNode == null ||
+ frame.state.previousNode == null ||
+ (frame.state.currentNode.pano && !frame.state.currentNode.fullPano) ||
+ (frame.state.previousNode.pano && !frame.state.previousNode.fullPano) ||
+ (frame.state.currentNode.fullPano && !frame.state.previousNode.fullPano));
+ }), operators_1.distinctUntilChanged())).pipe(operators_1.map(function (_a) {
+ var sliderVisible = _a[0], enabledState = _a[1];
+ return sliderVisible && enabledState;
+ }), operators_1.distinctUntilChanged());
+ this._waitSubscription = rxjs_1.combineLatest(mode$, motionless$, fullPano$, sliderVisible$).pipe(operators_1.withLatestFrom(this._navigator.stateService.state$))
+ .subscribe(function (_a) {
+ var _b = _a[0], mode = _b[0], motionless = _b[1], fullPano = _b[2], sliderVisible = _b[3], state = _a[1];
+ var interactive = sliderVisible &&
+ (motionless || mode === Component_1.SliderMode.Stationary || fullPano);
+ if (interactive && state !== State_1.State.WaitingInteractively) {
+ _this._navigator.stateService.waitInteractively();
+ }
+ else if (!interactive && state !== State_1.State.Waiting) {
+ _this._navigator.stateService.wait();
+ }
+ });
+ this._moveSubscription = rxjs_1.combineLatest(position$, mode$, motionless$, fullPano$, sliderVisible$)
+ .subscribe(function (_a) {
+ var position = _a[0], mode = _a[1], motionless = _a[2], fullPano = _a[3], sliderVisible = _a[4];
+ if (motionless || mode === Component_1.SliderMode.Stationary || fullPano) {
+ _this._navigator.stateService.moveTo(1);
+ }
+ else {
+ _this._navigator.stateService.moveTo(position);
+ }
+ });
+ this._domRenderSubscription = rxjs_1.combineLatest(position$, mode$, motionless$, fullPano$, sliderVisible$, this._container.renderService.size$).pipe(operators_1.map(function (_a) {
+ var position = _a[0], mode = _a[1], motionless = _a[2], fullPano = _a[3], sliderVisible = _a[4], size = _a[5];
+ return {
+ name: _this._name,
+ vnode: _this._domRenderer.render(position, mode, motionless, fullPano, sliderVisible),
+ };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ this._glRendererCreator$.next(null);
+ this._updateCurtainSubscription = rxjs_1.combineLatest(position$, fullPano$, sliderVisible$, this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$).pipe(operators_1.map(function (_a) {
+ var position = _a[0], fullPano = _a[1], visible = _a[2], render = _a[3], transform = _a[4];
+ if (!fullPano) {
+ return visible ? position : 1;
+ }
+ var basicMin = _this._viewportCoords.viewportToBasic(-1.15, 0, transform, render.perspective);
+ var basicMax = _this._viewportCoords.viewportToBasic(1.15, 0, transform, render.perspective);
+ var shiftedMax = basicMax[0] < basicMin[0] ? basicMax[0] + 1 : basicMax[0];
+ var basicPosition = basicMin[0] + position * (shiftedMax - basicMin[0]);
+ return basicPosition > 1 ? basicPosition - 1 : basicPosition;
+ }), operators_1.map(function (position) {
+ return function (glRenderer) {
+ glRenderer.updateCurtain(position);
+ return glRenderer;
+ };
+ }))
+ .subscribe(this._glRendererOperation$);
+ this._stateSubscription = rxjs_1.combineLatest(this._navigator.stateService.currentState$, mode$).pipe(operators_1.map(function (_a) {
+ var frame = _a[0], mode = _a[1];
+ return function (glRenderer) {
+ glRenderer.update(frame, mode);
+ return glRenderer;
+ };
+ }))
+ .subscribe(this._glRendererOperation$);
+ this._setKeysSubscription = this._configuration$.pipe(operators_1.filter(function (configuration) {
+ return configuration.keys != null;
+ }), operators_1.switchMap(function (configuration) {
+ return rxjs_1.zip(rxjs_1.zip(_this._catchCacheNode$(configuration.keys.background), _this._catchCacheNode$(configuration.keys.foreground)).pipe(operators_1.map(function (nodes) {
+ return { background: nodes[0], foreground: nodes[1] };
+ })), _this._navigator.stateService.currentState$.pipe(operators_1.first())).pipe(operators_1.map(function (nf) {
+ return { nodes: nf[0], state: nf[1].state };
+ }));
+ }))
+ .subscribe(function (co) {
+ if (co.state.currentNode != null &&
+ co.state.previousNode != null &&
+ co.state.currentNode.key === co.nodes.foreground.key &&
+ co.state.previousNode.key === co.nodes.background.key) {
+ return;
+ }
+ if (co.state.currentNode.key === co.nodes.background.key) {
+ _this._navigator.stateService.setNodes([co.nodes.foreground]);
+ return;
+ }
+ if (co.state.currentNode.key === co.nodes.foreground.key &&
+ co.state.trajectory.length === 1) {
+ _this._navigator.stateService.prependNodes([co.nodes.background]);
+ return;
+ }
+ _this._navigator.stateService.setNodes([co.nodes.background]);
+ _this._navigator.stateService.setNodes([co.nodes.foreground]);
+ }, function (e) {
+ console.error(e);
+ });
+ var previousNode$ = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return frame.state.previousNode;
+ }), operators_1.filter(function (node) {
+ return node != null;
+ }), operators_1.distinctUntilChanged(undefined, function (node) {
+ return node.key;
+ }));
+ var textureProvider$ = this._navigator.stateService.currentState$.pipe(operators_1.distinctUntilChanged(undefined, function (frame) {
+ return frame.state.currentNode.key;
+ }), operators_1.withLatestFrom(this._container.glRenderer.webGLRenderer$, this._container.renderService.size$), operators_1.map(function (_a) {
+ var frame = _a[0], renderer = _a[1], size = _a[2];
+ var state = frame.state;
+ var viewportSize = Math.max(size.width, size.height);
+ var currentNode = state.currentNode;
+ var currentTransform = state.currentTransform;
+ var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+ return new Tiles_1.TextureProvider(currentNode.key, currentTransform.basicWidth, currentTransform.basicHeight, tileSize, currentNode.image, _this._imageTileLoader, new Tiles_1.ImageTileStore(), renderer);
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ this._textureProviderSubscription = textureProvider$.subscribe(function () { });
+ this._setTextureProviderSubscription = textureProvider$.pipe(operators_1.map(function (provider) {
+ return function (renderer) {
+ renderer.setTextureProvider(provider.key, provider);
+ return renderer;
+ };
+ }))
+ .subscribe(this._glRendererOperation$);
+ this._setTileSizeSubscription = this._container.renderService.size$.pipe(operators_1.switchMap(function (size) {
+ return rxjs_1.combineLatest(textureProvider$, rxjs_1.of(size)).pipe(operators_1.first());
+ }))
+ .subscribe(function (_a) {
+ var provider = _a[0], size = _a[1];
+ var viewportSize = Math.max(size.width, size.height);
+ var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+ provider.setTileSize(tileSize);
+ });
+ this._abortTextureProviderSubscription = textureProvider$.pipe(operators_1.pairwise())
+ .subscribe(function (pair) {
+ var previous = pair[0];
+ previous.abort();
+ });
+ var roiTrigger$ = rxjs_1.combineLatest(this._container.renderService.renderCameraFrame$, this._container.renderService.size$.pipe(operators_1.debounceTime(250))).pipe(operators_1.map(function (_a) {
+ var camera = _a[0], size = _a[1];
+ return [
+ camera.camera.position.clone(),
+ camera.camera.lookat.clone(),
+ camera.zoom.valueOf(),
+ size.height.valueOf(),
+ size.width.valueOf()
+ ];
+ }), operators_1.pairwise(), operators_1.skipWhile(function (pls) {
+ return pls[1][2] - pls[0][2] < 0 || pls[1][2] === 0;
+ }), operators_1.map(function (pls) {
+ var samePosition = pls[0][0].equals(pls[1][0]);
+ var sameLookat = pls[0][1].equals(pls[1][1]);
+ var sameZoom = pls[0][2] === pls[1][2];
+ var sameHeight = pls[0][3] === pls[1][3];
+ var sameWidth = pls[0][4] === pls[1][4];
+ return samePosition && sameLookat && sameZoom && sameHeight && sameWidth;
+ }), operators_1.distinctUntilChanged(), operators_1.filter(function (stalled) {
+ return stalled;
+ }), operators_1.switchMap(function (stalled) {
+ return _this._container.renderService.renderCameraFrame$.pipe(operators_1.first());
+ }), operators_1.withLatestFrom(this._container.renderService.size$, this._navigator.stateService.currentTransform$));
+ this._setRegionOfInterestSubscription = textureProvider$.pipe(operators_1.switchMap(function (provider) {
+ return roiTrigger$.pipe(operators_1.map(function (_a) {
+ var camera = _a[0], size = _a[1], transform = _a[2];
+ return [
+ _this._roiCalculator.computeRegionOfInterest(camera, size, transform),
+ provider,
+ ];
+ }));
+ }), operators_1.filter(function (args) {
+ return !args[1].disposed;
+ }))
+ .subscribe(function (args) {
+ var roi = args[0];
+ var provider = args[1];
+ provider.setRegionOfInterest(roi);
+ });
+ var hasTexture$ = textureProvider$.pipe(operators_1.switchMap(function (provider) {
+ return provider.hasTexture$;
+ }), operators_1.startWith(false), operators_1.publishReplay(1), operators_1.refCount());
+ this._hasTextureSubscription = hasTexture$.subscribe(function () { });
+ var nodeImage$ = this._navigator.stateService.currentState$.pipe(operators_1.filter(function (frame) {
+ return frame.state.nodesAhead === 0;
+ }), operators_1.map(function (frame) {
+ return frame.state.currentNode;
+ }), operators_1.distinctUntilChanged(undefined, function (node) {
+ return node.key;
+ }), operators_1.debounceTime(1000), operators_1.withLatestFrom(hasTexture$), operators_1.filter(function (args) {
+ return !args[1];
+ }), operators_1.map(function (args) {
+ return args[0];
+ }), operators_1.filter(function (node) {
+ return node.pano ?
+ Utils_1.Settings.maxImageSize > Utils_1.Settings.basePanoramaSize :
+ Utils_1.Settings.maxImageSize > Utils_1.Settings.baseImageSize;
+ }), operators_1.switchMap(function (node) {
+ var baseImageSize = node.pano ?
+ Utils_1.Settings.basePanoramaSize :
+ Utils_1.Settings.baseImageSize;
+ if (Math.max(node.image.width, node.image.height) > baseImageSize) {
+ return rxjs_1.empty();
+ }
+ var image$ = node
+ .cacheImage$(Utils_1.Settings.maxImageSize).pipe(operators_1.map(function (n) {
+ return [n.image, n];
+ }));
+ return image$.pipe(operators_1.takeUntil(hasTexture$.pipe(operators_1.filter(function (hasTexture) {
+ return hasTexture;
+ }))), operators_1.catchError(function (error, caught) {
+ console.error("Failed to fetch high res image (" + node.key + ")", error);
+ return rxjs_1.empty();
+ }));
+ })).pipe(operators_1.publish(), operators_1.refCount());
+ this._updateBackgroundSubscription = nodeImage$.pipe(operators_1.withLatestFrom(textureProvider$))
+ .subscribe(function (args) {
+ if (args[0][1].key !== args[1].key ||
+ args[1].disposed) {
+ return;
+ }
+ args[1].updateBackground(args[0][0]);
+ });
+ this._updateTextureImageSubscription = nodeImage$.pipe(operators_1.map(function (imn) {
+ return function (renderer) {
+ renderer.updateTextureImage(imn[0], imn[1]);
+ return renderer;
+ };
+ }))
+ .subscribe(this._glRendererOperation$);
+ var textureProviderPrev$ = this._navigator.stateService.currentState$.pipe(operators_1.filter(function (frame) {
+ return !!frame.state.previousNode;
+ }), operators_1.distinctUntilChanged(undefined, function (frame) {
+ return frame.state.previousNode.key;
+ }), operators_1.withLatestFrom(this._container.glRenderer.webGLRenderer$, this._container.renderService.size$), operators_1.map(function (_a) {
+ var frame = _a[0], renderer = _a[1], size = _a[2];
+ var state = frame.state;
+ var viewportSize = Math.max(size.width, size.height);
+ var previousNode = state.previousNode;
+ var previousTransform = state.previousTransform;
+ var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+ return new Tiles_1.TextureProvider(previousNode.key, previousTransform.basicWidth, previousTransform.basicHeight, tileSize, previousNode.image, _this._imageTileLoader, new Tiles_1.ImageTileStore(), renderer);
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ this._textureProviderSubscriptionPrev = textureProviderPrev$.subscribe(function () { });
+ this._setTextureProviderSubscriptionPrev = textureProviderPrev$.pipe(operators_1.map(function (provider) {
+ return function (renderer) {
+ renderer.setTextureProviderPrev(provider.key, provider);
+ return renderer;
+ };
+ }))
+ .subscribe(this._glRendererOperation$);
+ this._setTileSizeSubscriptionPrev = this._container.renderService.size$.pipe(operators_1.switchMap(function (size) {
+ return rxjs_1.combineLatest(textureProviderPrev$, rxjs_1.of(size)).pipe(operators_1.first());
+ }))
+ .subscribe(function (_a) {
+ var provider = _a[0], size = _a[1];
+ var viewportSize = Math.max(size.width, size.height);
+ var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+ provider.setTileSize(tileSize);
+ });
+ this._abortTextureProviderSubscriptionPrev = textureProviderPrev$.pipe(operators_1.pairwise())
+ .subscribe(function (pair) {
+ var previous = pair[0];
+ previous.abort();
+ });
+ var roiTriggerPrev$ = rxjs_1.combineLatest(this._container.renderService.renderCameraFrame$, this._container.renderService.size$.pipe(operators_1.debounceTime(250))).pipe(operators_1.map(function (_a) {
+ var camera = _a[0], size = _a[1];
+ return [
+ camera.camera.position.clone(),
+ camera.camera.lookat.clone(),
+ camera.zoom.valueOf(),
+ size.height.valueOf(),
+ size.width.valueOf()
+ ];
+ }), operators_1.pairwise(), operators_1.skipWhile(function (pls) {
+ return pls[1][2] - pls[0][2] < 0 || pls[1][2] === 0;
+ }), operators_1.map(function (pls) {
+ var samePosition = pls[0][0].equals(pls[1][0]);
+ var sameLookat = pls[0][1].equals(pls[1][1]);
+ var sameZoom = pls[0][2] === pls[1][2];
+ var sameHeight = pls[0][3] === pls[1][3];
+ var sameWidth = pls[0][4] === pls[1][4];
+ return samePosition && sameLookat && sameZoom && sameHeight && sameWidth;
+ }), operators_1.distinctUntilChanged(), operators_1.filter(function (stalled) {
+ return stalled;
+ }), operators_1.switchMap(function (stalled) {
+ return _this._container.renderService.renderCameraFrame$.pipe(operators_1.first());
+ }), operators_1.withLatestFrom(this._container.renderService.size$, this._navigator.stateService.currentTransform$));
+ this._setRegionOfInterestSubscriptionPrev = textureProviderPrev$.pipe(operators_1.switchMap(function (provider) {
+ return roiTriggerPrev$.pipe(operators_1.map(function (_a) {
+ var camera = _a[0], size = _a[1], transform = _a[2];
+ return [
+ _this._roiCalculator.computeRegionOfInterest(camera, size, transform),
+ provider,
+ ];
+ }));
+ }), operators_1.filter(function (args) {
+ return !args[1].disposed;
+ }), operators_1.withLatestFrom(this._navigator.stateService.currentState$))
+ .subscribe(function (_a) {
+ var _b = _a[0], roi = _b[0], provider = _b[1], frame = _a[1];
+ var shiftedRoi = null;
+ if (frame.state.previousNode.fullPano) {
+ if (frame.state.currentNode.fullPano) {
+ var currentViewingDirection = _this._spatial.viewingDirection(frame.state.currentNode.rotation);
+ var previousViewingDirection = _this._spatial.viewingDirection(frame.state.previousNode.rotation);
+ var directionDiff = _this._spatial.angleBetweenVector2(currentViewingDirection.x, currentViewingDirection.y, previousViewingDirection.x, previousViewingDirection.y);
+ var shift = directionDiff / (2 * Math.PI);
+ var bbox = {
+ maxX: _this._spatial.wrap(roi.bbox.maxX + shift, 0, 1),
+ maxY: roi.bbox.maxY,
+ minX: _this._spatial.wrap(roi.bbox.minX + shift, 0, 1),
+ minY: roi.bbox.minY,
+ };
+ shiftedRoi = {
+ bbox: bbox,
+ pixelHeight: roi.pixelHeight,
+ pixelWidth: roi.pixelWidth,
+ };
+ }
+ else {
+ var currentViewingDirection = _this._spatial.viewingDirection(frame.state.currentNode.rotation);
+ var previousViewingDirection = _this._spatial.viewingDirection(frame.state.previousNode.rotation);
+ var directionDiff = _this._spatial.angleBetweenVector2(currentViewingDirection.x, currentViewingDirection.y, previousViewingDirection.x, previousViewingDirection.y);
+ var shiftX = directionDiff / (2 * Math.PI);
+ var a1 = _this._spatial.angleToPlane(currentViewingDirection.toArray(), [0, 0, 1]);
+ var a2 = _this._spatial.angleToPlane(previousViewingDirection.toArray(), [0, 0, 1]);
+ var shiftY = (a2 - a1) / (2 * Math.PI);
+ var currentTransform = frame.state.currentTransform;
+ var size = Math.max(currentTransform.basicWidth, currentTransform.basicHeight);
+ var hFov = size > 0 ?
+ 2 * Math.atan(0.5 * currentTransform.basicWidth / (size * currentTransform.focal)) :
+ Math.PI / 3;
+ var vFov = size > 0 ?
+ 2 * Math.atan(0.5 * currentTransform.basicHeight / (size * currentTransform.focal)) :
+ Math.PI / 3;
+ var spanningWidth = hFov / (2 * Math.PI);
+ var spanningHeight = vFov / Math.PI;
+ var basicWidth = (roi.bbox.maxX - roi.bbox.minX) * spanningWidth;
+ var basicHeight = (roi.bbox.maxY - roi.bbox.minY) * spanningHeight;
+ var pixelWidth = roi.pixelWidth * spanningWidth;
+ var pixelHeight = roi.pixelHeight * spanningHeight;
+ var zoomShiftX = (roi.bbox.minX + roi.bbox.maxX) / 2 - 0.5;
+ var zoomShiftY = (roi.bbox.minY + roi.bbox.maxY) / 2 - 0.5;
+ var minX = 0.5 + shiftX + spanningWidth * zoomShiftX - basicWidth / 2;
+ var maxX = 0.5 + shiftX + spanningWidth * zoomShiftX + basicWidth / 2;
+ var minY = 0.5 + shiftY + spanningHeight * zoomShiftY - basicHeight / 2;
+ var maxY = 0.5 + shiftY + spanningHeight * zoomShiftY + basicHeight / 2;
+ var bbox = {
+ maxX: _this._spatial.wrap(maxX, 0, 1),
+ maxY: maxY,
+ minX: _this._spatial.wrap(minX, 0, 1),
+ minY: minY,
+ };
+ shiftedRoi = {
+ bbox: bbox,
+ pixelHeight: pixelHeight,
+ pixelWidth: pixelWidth,
+ };
+ }
+ }
+ else {
+ var currentBasicAspect = frame.state.currentTransform.basicAspect;
+ var previousBasicAspect = frame.state.previousTransform.basicAspect;
+ var _c = _this._getBasicCorners(currentBasicAspect, previousBasicAspect), _d = _c[0], cornerMinX = _d[0], cornerMinY = _d[1], _e = _c[1], cornerMaxX = _e[0], cornerMaxY = _e[1];
+ var basicWidth = cornerMaxX - cornerMinX;
+ var basicHeight = cornerMaxY - cornerMinY;
+ var pixelWidth = roi.pixelWidth / basicWidth;
+ var pixelHeight = roi.pixelHeight / basicHeight;
+ var minX = (basicWidth - 1) / (2 * basicWidth) + roi.bbox.minX / basicWidth;
+ var maxX = (basicWidth - 1) / (2 * basicWidth) + roi.bbox.maxX / basicWidth;
+ var minY = (basicHeight - 1) / (2 * basicHeight) + roi.bbox.minY / basicHeight;
+ var maxY = (basicHeight - 1) / (2 * basicHeight) + roi.bbox.maxY / basicHeight;
+ var bbox = {
+ maxX: maxX,
+ maxY: maxY,
+ minX: minX,
+ minY: minY,
+ };
+ _this._clipBoundingBox(bbox);
+ shiftedRoi = {
+ bbox: bbox,
+ pixelHeight: pixelHeight,
+ pixelWidth: pixelWidth,
+ };
+ }
+ provider.setRegionOfInterest(shiftedRoi);
+ });
+ var hasTexturePrev$ = textureProviderPrev$.pipe(operators_1.switchMap(function (provider) {
+ return provider.hasTexture$;
+ }), operators_1.startWith(false), operators_1.publishReplay(1), operators_1.refCount());
+ this._hasTextureSubscriptionPrev = hasTexturePrev$.subscribe(function () { });
+ var nodeImagePrev$ = this._navigator.stateService.currentState$.pipe(operators_1.filter(function (frame) {
+ return frame.state.nodesAhead === 0 && !!frame.state.previousNode;
+ }), operators_1.map(function (frame) {
+ return frame.state.previousNode;
+ }), operators_1.distinctUntilChanged(undefined, function (node) {
+ return node.key;
+ }), operators_1.debounceTime(1000), operators_1.withLatestFrom(hasTexturePrev$), operators_1.filter(function (args) {
+ return !args[1];
+ }), operators_1.map(function (args) {
+ return args[0];
+ }), operators_1.filter(function (node) {
+ return node.pano ?
+ Utils_1.Settings.maxImageSize > Utils_1.Settings.basePanoramaSize :
+ Utils_1.Settings.maxImageSize > Utils_1.Settings.baseImageSize;
+ }), operators_1.switchMap(function (node) {
+ var baseImageSize = node.pano ?
+ Utils_1.Settings.basePanoramaSize :
+ Utils_1.Settings.baseImageSize;
+ if (Math.max(node.image.width, node.image.height) > baseImageSize) {
+ return rxjs_1.empty();
+ }
+ var image$ = node
+ .cacheImage$(Utils_1.Settings.maxImageSize).pipe(operators_1.map(function (n) {
+ return [n.image, n];
+ }));
+ return image$.pipe(operators_1.takeUntil(hasTexturePrev$.pipe(operators_1.filter(function (hasTexture) {
+ return hasTexture;
+ }))), operators_1.catchError(function (error, caught) {
+ console.error("Failed to fetch high res image (" + node.key + ")", error);
+ return rxjs_1.empty();
+ }));
+ })).pipe(operators_1.publish(), operators_1.refCount());
+ this._updateBackgroundSubscriptionPrev = nodeImagePrev$.pipe(operators_1.withLatestFrom(textureProviderPrev$))
+ .subscribe(function (args) {
+ if (args[0][1].key !== args[1].key ||
+ args[1].disposed) {
+ return;
+ }
+ args[1].updateBackground(args[0][0]);
+ });
+ this._updateTextureImageSubscriptionPrev = nodeImagePrev$.pipe(operators_1.map(function (imn) {
+ return function (renderer) {
+ renderer.updateTextureImage(imn[0], imn[1]);
+ return renderer;
+ };
+ }))
+ .subscribe(this._glRendererOperation$);
+ };
+ SliderComponent.prototype._deactivate = function () {
+ var _this = this;
+ this._waitSubscription.unsubscribe();
+ this._navigator.stateService.state$.pipe(operators_1.first())
+ .subscribe(function (state) {
+ if (state !== State_1.State.Traversing) {
+ _this._navigator.stateService.traverse();
+ }
+ });
+ this._glRendererDisposer$.next(null);
+ this._domRenderer.deactivate();
+ this._modeSubcription.unsubscribe();
+ this._setKeysSubscription.unsubscribe();
+ this._stateSubscription.unsubscribe();
+ this._glRenderSubscription.unsubscribe();
+ this._domRenderSubscription.unsubscribe();
+ this._moveSubscription.unsubscribe();
+ this._updateCurtainSubscription.unsubscribe();
+ this._textureProviderSubscription.unsubscribe();
+ this._setTextureProviderSubscription.unsubscribe();
+ this._setTileSizeSubscription.unsubscribe();
+ this._abortTextureProviderSubscription.unsubscribe();
+ this._setRegionOfInterestSubscription.unsubscribe();
+ this._hasTextureSubscription.unsubscribe();
+ this._updateBackgroundSubscription.unsubscribe();
+ this._updateTextureImageSubscription.unsubscribe();
+ this._textureProviderSubscriptionPrev.unsubscribe();
+ this._setTextureProviderSubscriptionPrev.unsubscribe();
+ this._setTileSizeSubscriptionPrev.unsubscribe();
+ this._abortTextureProviderSubscriptionPrev.unsubscribe();
+ this._setRegionOfInterestSubscriptionPrev.unsubscribe();
+ this._hasTextureSubscriptionPrev.unsubscribe();
+ this._updateBackgroundSubscriptionPrev.unsubscribe();
+ this._updateTextureImageSubscriptionPrev.unsubscribe();
+ this.configure({ keys: null });
+ };
+ SliderComponent.prototype._getDefaultConfiguration = function () {
+ return {
+ initialPosition: 1,
+ mode: Component_1.SliderMode.Motion,
+ sliderVisible: true,
+ };
+ };
+ SliderComponent.prototype._catchCacheNode$ = function (key) {
+ return this._navigator.graphService.cacheNode$(key).pipe(operators_1.catchError(function (error, caught) {
+ console.error("Failed to cache slider node (" + key + ")", error);
+ return rxjs_1.empty();
+ }));
+ };
+ SliderComponent.prototype._getBasicCorners = function (currentAspect, previousAspect) {
+ var offsetX;
+ var offsetY;
+ if (currentAspect > previousAspect) {
+ offsetX = 0.5;
+ offsetY = 0.5 * currentAspect / previousAspect;
+ }
+ else {
+ offsetX = 0.5 * previousAspect / currentAspect;
+ offsetY = 0.5;
+ }
+ return [[0.5 - offsetX, 0.5 - offsetY], [0.5 + offsetX, 0.5 + offsetY]];
+ };
+ SliderComponent.prototype._clipBoundingBox = function (bbox) {
+ bbox.minX = Math.max(0, Math.min(1, bbox.minX));
+ bbox.maxX = Math.max(0, Math.min(1, bbox.maxX));
+ bbox.minY = Math.max(0, Math.min(1, bbox.minY));
+ bbox.maxY = Math.max(0, Math.min(1, bbox.maxY));
+ };
+ SliderComponent.componentName = "slider";
+ return SliderComponent;
+}(Component_1.Component));
+exports.SliderComponent = SliderComponent;
+Component_1.ComponentService.register(SliderComponent);
+exports.default = SliderComponent;
+
+
+},{"../../Component":275,"../../Geo":278,"../../Render":281,"../../State":282,"../../Tiles":284,"../../Utils":285,"rxjs":27,"rxjs/operators":225}],338:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var vd = require("virtual-dom");
+var Component_1 = require("../../Component");
+var SliderDOMRenderer = /** @class */ (function () {
+ function SliderDOMRenderer(container) {
+ this._container = container;
+ this._interacting = false;
+ this._notifyModeChanged$ = new rxjs_1.Subject();
+ this._notifyPositionChanged$ = new rxjs_1.Subject();
+ this._stopInteractionSubscription = null;
+ }
+ Object.defineProperty(SliderDOMRenderer.prototype, "mode$", {
+ get: function () {
+ return this._notifyModeChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SliderDOMRenderer.prototype, "position$", {
+ get: function () {
+ return this._notifyPositionChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ SliderDOMRenderer.prototype.activate = function () {
+ var _this = this;
+ if (!!this._stopInteractionSubscription) {
+ return;
+ }
+ this._stopInteractionSubscription = rxjs_1.merge(this._container.mouseService.documentMouseUp$, this._container.touchService.touchEnd$.pipe(operators_1.filter(function (touchEvent) {
+ return touchEvent.touches.length === 0;
+ })))
+ .subscribe(function (event) {
+ if (_this._interacting) {
+ _this._interacting = false;
+ }
+ });
+ };
+ SliderDOMRenderer.prototype.deactivate = function () {
+ if (!this._stopInteractionSubscription) {
+ return;
+ }
+ this._interacting = false;
+ this._stopInteractionSubscription.unsubscribe();
+ this._stopInteractionSubscription = null;
+ };
+ SliderDOMRenderer.prototype.render = function (position, mode, motionless, pano, visible) {
+ var children = [];
+ if (visible) {
+ children.push(vd.h("div.SliderBorder", []));
+ var modeVisible = !(motionless || pano);
+ if (modeVisible) {
+ children.push(this._createModeButton(mode));
+ children.push(this._createModeButton2d(mode));
+ }
+ children.push(this._createPositionInput(position, modeVisible));
+ }
+ var boundingRect = this._container.domContainer.getBoundingClientRect();
+ var width = Math.max(215, Math.min(400, boundingRect.width - 100));
+ return vd.h("div.SliderContainer", { style: { width: width + "px" } }, children);
+ };
+ SliderDOMRenderer.prototype._createModeButton = function (mode) {
+ var _this = this;
+ var properties = {
+ onclick: function () {
+ if (mode === Component_1.SliderMode.Motion) {
+ return;
+ }
+ _this._notifyModeChanged$.next(Component_1.SliderMode.Motion);
+ },
+ };
+ var className = mode === Component_1.SliderMode.Stationary ?
+ "SliderModeButtonDisabled" :
+ "SliderModeButton";
+ return vd.h("div." + className, properties, [vd.h("div.SliderModeIcon", [])]);
+ };
+ SliderDOMRenderer.prototype._createModeButton2d = function (mode) {
+ var _this = this;
+ var properties = {
+ onclick: function () {
+ if (mode === Component_1.SliderMode.Stationary) {
+ return;
+ }
+ _this._notifyModeChanged$.next(Component_1.SliderMode.Stationary);
+ },
+ };
+ var className = mode === Component_1.SliderMode.Motion ?
+ "SliderModeButton2dDisabled" :
+ "SliderModeButton2d";
+ return vd.h("div." + className, properties, [vd.h("div.SliderModeIcon2d", [])]);
+ };
+ SliderDOMRenderer.prototype._createPositionInput = function (position, modeVisible) {
+ var _this = this;
+ var onChange = function (e) {
+ _this._notifyPositionChanged$.next(Number(e.target.value) / 1000);
+ };
+ var onStart = function (e) {
+ _this._interacting = true;
+ e.stopPropagation();
+ };
+ var onMove = function (e) {
+ if (_this._interacting) {
+ e.stopPropagation();
+ }
+ };
+ var onKeyDown = function (e) {
+ if (e.key === "ArrowDown" || e.key === "ArrowLeft" ||
+ e.key === "ArrowRight" || e.key === "ArrowUp") {
+ e.preventDefault();
+ }
+ };
+ var boundingRect = this._container.domContainer.getBoundingClientRect();
+ var width = Math.max(215, Math.min(400, boundingRect.width - 105)) - 84 + (modeVisible ? 0 : 52);
+ var positionInput = vd.h("input.SliderPosition", {
+ max: 1000,
+ min: 0,
+ onchange: onChange,
+ oninput: onChange,
+ onkeydown: onKeyDown,
+ onmousedown: onStart,
+ onmousemove: onMove,
+ ontouchmove: onMove,
+ ontouchstart: onStart,
+ style: {
+ width: width + "px",
+ },
+ type: "range",
+ value: 1000 * position,
+ }, []);
+ return vd.h("div.SliderPositionContainer", [positionInput]);
+ };
+ return SliderDOMRenderer;
+}());
+exports.SliderDOMRenderer = SliderDOMRenderer;
+exports.default = SliderDOMRenderer;
+
+},{"../../Component":275,"rxjs":27,"rxjs/operators":225,"virtual-dom":231}],339:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../Component");
+var Geo_1 = require("../../Geo");
+var SliderGLRenderer = /** @class */ (function () {
+ function SliderGLRenderer() {
+ this._factory = new Component_1.MeshFactory();
+ this._scene = new Component_1.MeshScene();
+ this._spatial = new Geo_1.Spatial();
+ this._currentKey = null;
+ this._previousKey = null;
+ this._disabled = false;
+ this._curtain = 1;
+ this._frameId = 0;
+ this._needsRender = false;
+ this._mode = null;
+ this._currentProviderDisposers = {};
+ this._previousProviderDisposers = {};
+ }
+ Object.defineProperty(SliderGLRenderer.prototype, "disabled", {
+ get: function () {
+ return this._disabled;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SliderGLRenderer.prototype, "frameId", {
+ get: function () {
+ return this._frameId;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(SliderGLRenderer.prototype, "needsRender", {
+ get: function () {
+ return this._needsRender;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ SliderGLRenderer.prototype.setTextureProvider = function (key, provider) {
+ this._setTextureProvider(key, this._currentKey, provider, this._currentProviderDisposers, this._updateTexture.bind(this));
+ };
+ SliderGLRenderer.prototype.setTextureProviderPrev = function (key, provider) {
+ this._setTextureProvider(key, this._previousKey, provider, this._previousProviderDisposers, this._updateTexturePrev.bind(this));
+ };
+ SliderGLRenderer.prototype.update = function (frame, mode) {
+ this._updateFrameId(frame.id);
+ this._updateImagePlanes(frame.state, mode);
+ };
+ SliderGLRenderer.prototype.updateCurtain = function (curtain) {
+ if (this._curtain === curtain) {
+ return;
+ }
+ this._curtain = curtain;
+ this._updateCurtain();
+ this._needsRender = true;
+ };
+ SliderGLRenderer.prototype.updateTexture = function (image, node) {
+ var planes = node.key === this._currentKey ?
+ this._scene.planes :
+ node.key === this._previousKey ?
+ this._scene.planesOld :
+ {};
+ if (Object.keys(planes).length === 0) {
+ return;
+ }
+ this._needsRender = true;
+ for (var key in planes) {
+ if (!planes.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planes[key];
+ var material = plane.material;
+ var texture = material.uniforms.projectorTex.value;
+ texture.image = image;
+ texture.needsUpdate = true;
+ }
+ };
+ SliderGLRenderer.prototype.updateTextureImage = function (image, node) {
+ if (this._currentKey !== node.key) {
+ return;
+ }
+ this._needsRender = true;
+ var planes = this._scene.planes;
+ for (var key in planes) {
+ if (!planes.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planes[key];
+ var material = plane.material;
+ var texture = material.uniforms.projectorTex.value;
+ texture.image = image;
+ texture.needsUpdate = true;
+ }
+ };
+ SliderGLRenderer.prototype.render = function (perspectiveCamera, renderer) {
+ if (!this.disabled) {
+ renderer.render(this._scene.sceneOld, perspectiveCamera);
+ }
+ renderer.render(this._scene.scene, perspectiveCamera);
+ this._needsRender = false;
+ };
+ SliderGLRenderer.prototype.dispose = function () {
+ this._scene.clear();
+ for (var key in this._currentProviderDisposers) {
+ if (!this._currentProviderDisposers.hasOwnProperty(key)) {
+ continue;
+ }
+ this._currentProviderDisposers[key]();
+ }
+ for (var key in this._previousProviderDisposers) {
+ if (!this._previousProviderDisposers.hasOwnProperty(key)) {
+ continue;
+ }
+ this._previousProviderDisposers[key]();
+ }
+ this._currentProviderDisposers = {};
+ this._previousProviderDisposers = {};
+ };
+ SliderGLRenderer.prototype._getBasicCorners = function (currentAspect, previousAspect) {
+ var offsetX;
+ var offsetY;
+ if (currentAspect > previousAspect) {
+ offsetX = 0.5;
+ offsetY = 0.5 * currentAspect / previousAspect;
+ }
+ else {
+ offsetX = 0.5 * previousAspect / currentAspect;
+ offsetY = 0.5;
+ }
+ return [[0.5 - offsetX, 0.5 - offsetY], [0.5 + offsetX, 0.5 + offsetY]];
+ };
+ SliderGLRenderer.prototype._setDisabled = function (state) {
+ this._disabled = state.currentNode == null ||
+ state.previousNode == null ||
+ (state.currentNode.pano && !state.currentNode.fullPano) ||
+ (state.previousNode.pano && !state.previousNode.fullPano) ||
+ (state.currentNode.fullPano && !state.previousNode.fullPano);
+ };
+ SliderGLRenderer.prototype._setTextureProvider = function (key, originalKey, provider, providerDisposers, updateTexture) {
+ var _this = this;
+ if (key !== originalKey) {
+ return;
+ }
+ var createdSubscription = provider.textureCreated$
+ .subscribe(updateTexture);
+ var updatedSubscription = provider.textureUpdated$
+ .subscribe(function (updated) {
+ _this._needsRender = true;
+ });
+ var dispose = function () {
+ createdSubscription.unsubscribe();
+ updatedSubscription.unsubscribe();
+ provider.dispose();
+ };
+ if (key in providerDisposers) {
+ var disposeProvider = providerDisposers[key];
+ disposeProvider();
+ delete providerDisposers[key];
+ }
+ providerDisposers[key] = dispose;
+ };
+ SliderGLRenderer.prototype._updateCurtain = function () {
+ var planes = this._scene.planes;
+ for (var key in planes) {
+ if (!planes.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planes[key];
+ var shaderMaterial = plane.material;
+ if (!!shaderMaterial.uniforms.curtain) {
+ shaderMaterial.uniforms.curtain.value = this._curtain;
+ }
+ }
+ };
+ SliderGLRenderer.prototype._updateFrameId = function (frameId) {
+ this._frameId = frameId;
+ };
+ SliderGLRenderer.prototype._updateImagePlanes = function (state, mode) {
+ var currentChanged = state.currentNode != null && this._currentKey !== state.currentNode.key;
+ var previousChanged = state.previousNode != null && this._previousKey !== state.previousNode.key;
+ var modeChanged = this._mode !== mode;
+ if (!(currentChanged || previousChanged || modeChanged)) {
+ return;
+ }
+ this._setDisabled(state);
+ this._needsRender = true;
+ this._mode = mode;
+ var motionless = state.motionless || mode === Component_1.SliderMode.Stationary || state.currentNode.pano;
+ if (this.disabled || previousChanged) {
+ if (this._previousKey in this._previousProviderDisposers) {
+ this._previousProviderDisposers[this._previousKey]();
+ delete this._previousProviderDisposers[this._previousKey];
+ }
+ }
+ if (this.disabled) {
+ this._scene.setImagePlanesOld({});
+ }
+ else {
+ if (previousChanged || modeChanged) {
+ var previousNode = state.previousNode;
+ this._previousKey = previousNode.key;
+ var elements = state.currentTransform.rt.elements;
+ var translation = [elements[12], elements[13], elements[14]];
+ var currentAspect = state.currentTransform.basicAspect;
+ var previousAspect = state.previousTransform.basicAspect;
+ var textureScale = currentAspect > previousAspect ?
+ [1, previousAspect / currentAspect] :
+ [currentAspect / previousAspect, 1];
+ var rotation = state.currentNode.rotation;
+ var width = state.currentNode.width;
+ var height = state.currentNode.height;
+ if (previousNode.fullPano) {
+ rotation = state.previousNode.rotation;
+ translation = this._spatial
+ .rotate(this._spatial
+ .opticalCenter(state.currentNode.rotation, translation)
+ .toArray(), rotation)
+ .multiplyScalar(-1)
+ .toArray();
+ width = state.previousNode.width;
+ height = state.previousNode.height;
+ }
+ var transform = new Geo_1.Transform(state.currentNode.orientation, width, height, state.currentNode.focal, state.currentNode.scale, previousNode.gpano, rotation, translation, previousNode.image, textureScale);
+ var mesh = undefined;
+ if (previousNode.fullPano) {
+ mesh = this._factory.createMesh(previousNode, motionless || state.currentNode.fullPano ? transform : state.previousTransform);
+ }
+ else {
+ if (motionless) {
+ var _a = this._getBasicCorners(currentAspect, previousAspect), _b = _a[0], basicX0 = _b[0], basicY0 = _b[1], _c = _a[1], basicX1 = _c[0], basicY1 = _c[1];
+ mesh = this._factory.createFlatMesh(state.previousNode, transform, basicX0, basicX1, basicY0, basicY1);
+ }
+ else {
+ mesh = this._factory.createMesh(state.previousNode, state.previousTransform);
+ }
+ }
+ var previousPlanes = {};
+ previousPlanes[previousNode.key] = mesh;
+ this._scene.setImagePlanesOld(previousPlanes);
+ }
+ }
+ if (currentChanged || modeChanged) {
+ if (this._currentKey in this._currentProviderDisposers) {
+ this._currentProviderDisposers[this._currentKey]();
+ delete this._currentProviderDisposers[this._currentKey];
+ }
+ this._currentKey = state.currentNode.key;
+ var planes = {};
+ if (state.currentNode.fullPano) {
+ planes[state.currentNode.key] = this._factory.createCurtainMesh(state.currentNode, state.currentTransform);
+ }
+ else if (state.currentNode.pano && !state.currentNode.fullPano) {
+ planes[state.currentNode.key] = this._factory.createMesh(state.currentNode, state.currentTransform);
+ }
+ else {
+ if (motionless) {
+ planes[state.currentNode.key] = this._factory.createDistortedCurtainMesh(state.currentNode, state.currentTransform);
+ }
+ else {
+ planes[state.currentNode.key] = this._factory.createCurtainMesh(state.currentNode, state.currentTransform);
+ }
+ }
+ this._scene.setImagePlanes(planes);
+ this._updateCurtain();
+ }
+ };
+ SliderGLRenderer.prototype._updateTexture = function (texture) {
+ this._needsRender = true;
+ var planes = this._scene.planes;
+ for (var key in planes) {
+ if (!planes.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planes[key];
+ var material = plane.material;
+ var oldTexture = material.uniforms.projectorTex.value;
+ material.uniforms.projectorTex.value = null;
+ oldTexture.dispose();
+ material.uniforms.projectorTex.value = texture;
+ }
+ };
+ SliderGLRenderer.prototype._updateTexturePrev = function (texture) {
+ this._needsRender = true;
+ var planes = this._scene.planesOld;
+ for (var key in planes) {
+ if (!planes.hasOwnProperty(key)) {
+ continue;
+ }
+ var plane = planes[key];
+ var material = plane.material;
+ var oldTexture = material.uniforms.projectorTex.value;
+ material.uniforms.projectorTex.value = null;
+ oldTexture.dispose();
+ material.uniforms.projectorTex.value = texture;
+ }
+ };
+ return SliderGLRenderer;
+}());
+exports.SliderGLRenderer = SliderGLRenderer;
+exports.default = SliderGLRenderer;
+
+
+},{"../../Component":275,"../../Geo":278}],340:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var geohash = require("latlon-geohash");
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Error_1 = require("../../Error");
+var Utils_1 = require("../../Utils");
+var SpatialDataCache = /** @class */ (function () {
+ function SpatialDataCache(graphService) {
+ this._graphService = graphService;
+ this._tiles = {};
+ this._cacheRequests = {};
+ this._reconstructions = {};
+ this._cachingReconstructions$ = {};
+ this._cachingTiles$ = {};
+ }
+ SpatialDataCache.prototype.cacheReconstructions$ = function (hash) {
+ var _this = this;
+ if (!this.hasTile(hash)) {
+ throw new Error("Cannot cache reconstructions of a non-existing tile.");
+ }
+ if (this.hasReconstructions(hash)) {
+ throw new Error("Cannot cache reconstructions that already exists.");
+ }
+ if (this.isCachingReconstructions(hash)) {
+ return this._cachingReconstructions$[hash];
+ }
+ var tile = [];
+ if (hash in this._reconstructions) {
+ var reconstructionKeys = this.getReconstructions(hash)
+ .map(function (reconstruction) {
+ return reconstruction.data.key;
+ });
+ for (var _i = 0, _a = this.getTile(hash); _i < _a.length; _i++) {
+ var node = _a[_i];
+ if (reconstructionKeys.indexOf(node.key) === -1) {
+ tile.push(node);
+ }
+ }
+ }
+ else {
+ tile.push.apply(tile, this.getTile(hash));
+ this._reconstructions[hash] = [];
+ }
+ this._cacheRequests[hash] = [];
+ this._cachingReconstructions$[hash] = rxjs_1.from(tile).pipe(operators_1.mergeMap(function (nodeData) {
+ return !_this._cacheRequests[hash] ?
+ rxjs_1.empty() :
+ rxjs_1.zip(rxjs_1.of(nodeData), _this._getAtomicReconstruction(nodeData.key, _this._cacheRequests[hash]))
+ .pipe(operators_1.catchError(function (error) {
+ if (error instanceof Error_1.AbortMapillaryError) {
+ return rxjs_1.empty();
+ }
+ console.error(error);
+ return rxjs_1.of([nodeData, null]);
+ }));
+ }, 6), operators_1.map(function (_a) {
+ var nodeData = _a[0], reconstruction = _a[1];
+ return { data: nodeData, reconstruction: reconstruction };
+ }), operators_1.filter(function () {
+ return hash in _this._reconstructions;
+ }), operators_1.tap(function (data) {
+ _this._reconstructions[hash].push(data);
+ }), operators_1.filter(function (data) {
+ return !!data.reconstruction;
+ }), operators_1.finalize(function () {
+ if (hash in _this._cachingReconstructions$) {
+ delete _this._cachingReconstructions$[hash];
+ }
+ if (hash in _this._cacheRequests) {
+ delete _this._cacheRequests[hash];
+ }
+ }), operators_1.publish(), operators_1.refCount());
+ return this._cachingReconstructions$[hash];
+ };
+ SpatialDataCache.prototype.cacheTile$ = function (hash) {
+ var _this = this;
+ if (hash.length !== 8) {
+ throw new Error("Hash needs to be level 8.");
+ }
+ if (this.hasTile(hash)) {
+ throw new Error("Cannot cache tile that already exists.");
+ }
+ if (this.hasTile(hash)) {
+ return this._cachingTiles$[hash];
+ }
+ var bounds = geohash.bounds(hash);
+ var sw = { lat: bounds.sw.lat, lon: bounds.sw.lon };
+ var ne = { lat: bounds.ne.lat, lon: bounds.ne.lon };
+ this._tiles[hash] = [];
+ this._cachingTiles$[hash] = this._graphService.cacheBoundingBox$(sw, ne).pipe(operators_1.catchError(function (error) {
+ console.error(error);
+ delete _this._tiles[hash];
+ return rxjs_1.empty();
+ }), operators_1.map(function (nodes) {
+ return nodes
+ .map(function (n) {
+ return _this._createNodeData(n);
+ });
+ }), operators_1.filter(function () {
+ return hash in _this._tiles;
+ }), operators_1.tap(function (nodeData) {
+ var _a;
+ (_a = _this._tiles[hash]).push.apply(_a, nodeData);
+ delete _this._cachingTiles$[hash];
+ }), operators_1.finalize(function () {
+ if (hash in _this._cachingTiles$) {
+ delete _this._cachingTiles$[hash];
+ }
+ }), operators_1.publish(), operators_1.refCount());
+ return this._cachingTiles$[hash];
+ };
+ SpatialDataCache.prototype.isCachingReconstructions = function (hash) {
+ return hash in this._cachingReconstructions$;
+ };
+ SpatialDataCache.prototype.isCachingTile = function (hash) {
+ return hash in this._cachingTiles$;
+ };
+ SpatialDataCache.prototype.hasReconstructions = function (hash) {
+ return !(hash in this._cachingReconstructions$) &&
+ hash in this._reconstructions &&
+ this._reconstructions[hash].length === this._tiles[hash].length;
+ };
+ SpatialDataCache.prototype.hasTile = function (hash) {
+ return !(hash in this._cachingTiles$) && hash in this._tiles;
+ };
+ SpatialDataCache.prototype.getReconstructions = function (hash) {
+ return hash in this._reconstructions ?
+ this._reconstructions[hash]
+ .filter(function (data) {
+ return !!data.reconstruction;
+ }) :
+ [];
+ };
+ SpatialDataCache.prototype.getTile = function (hash) {
+ return hash in this._tiles ? this._tiles[hash] : [];
+ };
+ SpatialDataCache.prototype.uncache = function (keepHashes) {
+ for (var _i = 0, _a = Object.keys(this._cacheRequests); _i < _a.length; _i++) {
+ var hash = _a[_i];
+ if (!!keepHashes && keepHashes.indexOf(hash) !== -1) {
+ continue;
+ }
+ for (var _b = 0, _c = this._cacheRequests[hash]; _b < _c.length; _b++) {
+ var request = _c[_b];
+ request.abort();
+ }
+ delete this._cacheRequests[hash];
+ }
+ for (var _d = 0, _e = Object.keys(this._reconstructions); _d < _e.length; _d++) {
+ var hash = _e[_d];
+ if (!!keepHashes && keepHashes.indexOf(hash) !== -1) {
+ continue;
+ }
+ delete this._reconstructions[hash];
+ }
+ for (var _f = 0, _g = Object.keys(this._tiles); _f < _g.length; _f++) {
+ var hash = _g[_f];
+ if (!!keepHashes && keepHashes.indexOf(hash) !== -1) {
+ continue;
+ }
+ delete this._tiles[hash];
+ }
+ };
+ SpatialDataCache.prototype._createNodeData = function (node) {
+ return {
+ alt: node.alt,
+ cameraProjection: node.cameraProjection,
+ focal: node.focal,
+ gpano: node.gpano,
+ height: node.height,
+ k1: node.ck1,
+ k2: node.ck2,
+ key: node.key,
+ lat: node.latLon.lat,
+ lon: node.latLon.lon,
+ mergeCC: node.mergeCC,
+ orientation: node.orientation,
+ originalLat: node.originalLatLon.lat,
+ originalLon: node.originalLatLon.lon,
+ rotation: [node.rotation[0], node.rotation[1], node.rotation[2]],
+ scale: node.scale,
+ width: node.width,
+ };
+ };
+ SpatialDataCache.prototype._getAtomicReconstruction = function (key, requests) {
+ return rxjs_1.Observable.create(function (subscriber) {
+ var xmlHTTP = new XMLHttpRequest();
+ xmlHTTP.open("GET", Utils_1.Urls.atomicReconstruction(key), true);
+ xmlHTTP.responseType = "json";
+ xmlHTTP.timeout = 15000;
+ xmlHTTP.onload = function () {
+ if (!xmlHTTP.response) {
+ subscriber.error(new Error("Atomic reconstruction does not exist (" + key + ")"));
+ }
+ else {
+ subscriber.next(xmlHTTP.response);
+ subscriber.complete();
+ }
+ };
+ xmlHTTP.onerror = function () {
+ subscriber.error(new Error("Failed to get atomic reconstruction (" + key + ")"));
+ };
+ xmlHTTP.ontimeout = function () {
+ subscriber.error(new Error("Atomic reconstruction request timed out (" + key + ")"));
+ };
+ xmlHTTP.onabort = function () {
+ subscriber.error(new Error_1.AbortMapillaryError("Atomic reconstruction request was aborted (" + key + ")"));
+ };
+ requests.push(xmlHTTP);
+ xmlHTTP.send(null);
+ });
+ };
+ return SpatialDataCache;
+}());
+exports.SpatialDataCache = SpatialDataCache;
+exports.default = SpatialDataCache;
+
+},{"../../Error":277,"../../Utils":285,"latlon-geohash":21,"rxjs":27,"rxjs/operators":225}],341:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var geohash = require("latlon-geohash");
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../Component");
+var Geo_1 = require("../../Geo");
+var Render_1 = require("../../Render");
+var PlayService_1 = require("../../viewer/PlayService");
+var State_1 = require("../../state/State");
+var SpatialDataComponent = /** @class */ (function (_super) {
+ __extends(SpatialDataComponent, _super);
+ function SpatialDataComponent(name, container, navigator) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._cache = new Component_1.SpatialDataCache(navigator.graphService);
+ _this._scene = new Component_1.SpatialDataScene(_this._getDefaultConfiguration());
+ _this._viewportCoords = new Geo_1.ViewportCoords();
+ _this._geoCoords = new Geo_1.GeoCoords();
+ return _this;
+ }
+ SpatialDataComponent.prototype._activate = function () {
+ var _this = this;
+ this._earthControlsSubscription = this._configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.earthControls;
+ }), operators_1.distinctUntilChanged(), operators_1.withLatestFrom(this._navigator.stateService.state$))
+ .subscribe(function (_a) {
+ var earth = _a[0], state = _a[1];
+ if (earth && state !== State_1.default.Earth) {
+ _this._navigator.stateService.earth();
+ }
+ else if (!earth && state === State_1.default.Earth) {
+ _this._navigator.stateService.traverse();
+ }
+ });
+ var direction$ = this._container.renderService.bearing$.pipe(operators_1.map(function (bearing) {
+ var direction = "";
+ if (bearing > 292.5 || bearing <= 67.5) {
+ direction += "n";
+ }
+ if (bearing > 112.5 && bearing <= 247.5) {
+ direction += "s";
+ }
+ if (bearing > 22.5 && bearing <= 157.5) {
+ direction += "e";
+ }
+ if (bearing > 202.5 && bearing <= 337.5) {
+ direction += "w";
+ }
+ return direction;
+ }), operators_1.distinctUntilChanged(), operators_1.publishReplay(1), operators_1.refCount());
+ var hash$ = this._navigator.stateService.reference$.pipe(operators_1.tap(function () {
+ _this._scene.uncache();
+ }), operators_1.switchMap(function () {
+ return _this._navigator.stateService.currentNode$.pipe(operators_1.map(function (node) {
+ return geohash.encode(node.latLon.lat, node.latLon.lon, 8);
+ }), operators_1.distinctUntilChanged());
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ var sequencePlay$ = rxjs_1.combineLatest(this._navigator.playService.playing$, this._navigator.playService.speed$).pipe(operators_1.map(function (_a) {
+ var playing = _a[0], speed = _a[1];
+ return playing && speed > PlayService_1.default.sequenceSpeed;
+ }), operators_1.distinctUntilChanged(), operators_1.publishReplay(1), operators_1.refCount());
+ this._addSubscription = rxjs_1.combineLatest(this._navigator.stateService.state$.pipe(operators_1.map(function (state) {
+ return state === State_1.default.Earth;
+ }), operators_1.distinctUntilChanged()), hash$, sequencePlay$, direction$).pipe(operators_1.distinctUntilChanged(function (_a, _b) {
+ var e1 = _a[0], h1 = _a[1], s1 = _a[2], d1 = _a[3];
+ var e2 = _b[0], h2 = _b[1], s2 = _b[2], d2 = _b[3];
+ if (e1 !== e2) {
+ return false;
+ }
+ if (e1) {
+ return h1 === h2 && s1 === s2;
+ }
+ return h1 === h2 && s1 === s2 && d1 === d2;
+ }), operators_1.concatMap(function (_a) {
+ var earth = _a[0], hash = _a[1], sequencePlay = _a[2], direction = _a[3];
+ if (earth) {
+ return sequencePlay ?
+ rxjs_1.of([hash]) :
+ rxjs_1.of(_this._adjacentComponent(hash, 4));
+ }
+ return sequencePlay ?
+ rxjs_1.of([hash, geohash.neighbours(hash)[direction]]) :
+ rxjs_1.of(_this._computeTiles(hash, direction));
+ }), operators_1.switchMap(function (hashes) {
+ return rxjs_1.from(hashes).pipe(operators_1.mergeMap(function (h) {
+ var tile$;
+ if (_this._cache.hasTile(h)) {
+ tile$ = rxjs_1.of(_this._cache.getTile(h));
+ }
+ else if (_this._cache.isCachingTile(h)) {
+ tile$ = _this._cache.cacheTile$(h).pipe(operators_1.last(null, {}), operators_1.switchMap(function () {
+ return rxjs_1.of(_this._cache.getTile(h));
+ }));
+ }
+ else {
+ tile$ = _this._cache.cacheTile$(h);
+ }
+ return rxjs_1.combineLatest(rxjs_1.of(h), tile$);
+ }, 1), operators_1.map(function (_a) {
+ var hash = _a[0];
+ return hash;
+ }));
+ }), operators_1.concatMap(function (hash) {
+ var reconstructions$;
+ if (_this._cache.hasReconstructions(hash)) {
+ reconstructions$ = rxjs_1.from(_this._cache.getReconstructions(hash));
+ }
+ else if (_this._cache.isCachingReconstructions(hash)) {
+ reconstructions$ = _this._cache.cacheReconstructions$(hash).pipe(operators_1.last(null, {}), operators_1.switchMap(function () {
+ return rxjs_1.from(_this._cache.getReconstructions(hash));
+ }));
+ }
+ else if (_this._cache.hasTile(hash)) {
+ reconstructions$ = _this._cache.cacheReconstructions$(hash);
+ }
+ else {
+ reconstructions$ = rxjs_1.empty();
+ }
+ return rxjs_1.combineLatest(rxjs_1.of(hash), reconstructions$);
+ }), operators_1.withLatestFrom(this._navigator.stateService.reference$), operators_1.tap(function (_a) {
+ var hash = _a[0][0], reference = _a[1];
+ if (_this._scene.hasTile(hash)) {
+ return;
+ }
+ _this._scene.addTile(_this._computeTileBBox(hash, reference), hash);
+ }), operators_1.filter(function (_a) {
+ var _b = _a[0], hash = _b[0], data = _b[1];
+ return !_this._scene.hasReconstruction(data.reconstruction.main_shot, hash);
+ }), operators_1.map(function (_a) {
+ var _b = _a[0], hash = _b[0], data = _b[1], reference = _a[1];
+ return [
+ data,
+ _this._createTransform(data.data, reference),
+ _this._computeOriginalPosition(data.data, reference),
+ hash
+ ];
+ }))
+ .subscribe(function (_a) {
+ var data = _a[0], transform = _a[1], position = _a[2], hash = _a[3];
+ _this._scene.addReconstruction(data.reconstruction, transform, position, !!data.data.mergeCC ? data.data.mergeCC.toString() : "", hash);
+ });
+ this._cameraVisibilitySubscription = this._configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.camerasVisible;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (visible) {
+ _this._scene.setCameraVisibility(visible);
+ });
+ this._pointVisibilitySubscription = this._configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.pointsVisible;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (visible) {
+ _this._scene.setPointVisibility(visible);
+ });
+ this._positionVisibilitySubscription = this._configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.positionsVisible;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (visible) {
+ _this._scene.setPositionVisibility(visible);
+ });
+ this._tileVisibilitySubscription = this._configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.tilesVisible;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (visible) {
+ _this._scene.setTileVisibility(visible);
+ });
+ this._visualizeConnectedComponentSubscription = this._configuration$.pipe(operators_1.map(function (configuration) {
+ return configuration.connectedComponents;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (visualize) {
+ _this._scene.setConnectedComponentVisualization(visualize);
+ });
+ this._uncacheSubscription = hash$
+ .subscribe(function (hash) {
+ var keepHashes = _this._adjacentComponent(hash, 4);
+ _this._scene.uncache(keepHashes);
+ _this._cache.uncache(keepHashes);
+ });
+ this._moveSubscription = this._navigator.playService.playing$.pipe(operators_1.switchMap(function (playing) {
+ return playing ?
+ rxjs_1.empty() :
+ _this._container.mouseService.dblClick$;
+ }), operators_1.withLatestFrom(this._container.renderService.renderCamera$), operators_1.switchMap(function (_a) {
+ var event = _a[0], render = _a[1];
+ var element = _this._container.element;
+ var _b = _this._viewportCoords.canvasPosition(event, element), canvasX = _b[0], canvasY = _b[1];
+ var viewport = _this._viewportCoords.canvasToViewport(canvasX, canvasY, element);
+ var key = _this._scene.intersectObjects(viewport, render.perspective);
+ return !!key ?
+ _this._navigator.moveToKey$(key).pipe(operators_1.catchError(function () {
+ return rxjs_1.empty();
+ })) :
+ rxjs_1.empty();
+ }))
+ .subscribe();
+ this._renderSubscription = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ var scene = _this._scene;
+ return {
+ name: _this._name,
+ render: {
+ frameId: frame.id,
+ needsRender: scene.needsRender,
+ render: scene.render.bind(scene),
+ stage: Render_1.GLRenderStage.Foreground,
+ },
+ };
+ }))
+ .subscribe(this._container.glRenderer.render$);
+ };
+ SpatialDataComponent.prototype._deactivate = function () {
+ var _this = this;
+ this._cache.uncache();
+ this._scene.uncache();
+ this._addSubscription.unsubscribe();
+ this._cameraVisibilitySubscription.unsubscribe();
+ this._earthControlsSubscription.unsubscribe();
+ this._moveSubscription.unsubscribe();
+ this._pointVisibilitySubscription.unsubscribe();
+ this._positionVisibilitySubscription.unsubscribe();
+ this._renderSubscription.unsubscribe();
+ this._tileVisibilitySubscription.unsubscribe();
+ this._uncacheSubscription.unsubscribe();
+ this._visualizeConnectedComponentSubscription.unsubscribe();
+ this._navigator.stateService.state$.pipe(operators_1.first())
+ .subscribe(function (state) {
+ if (state === State_1.default.Earth) {
+ _this._navigator.stateService.traverse();
+ }
+ });
+ };
+ SpatialDataComponent.prototype._getDefaultConfiguration = function () {
+ return { camerasVisible: false, pointsVisible: true, positionsVisible: false, tilesVisible: false };
+ };
+ SpatialDataComponent.prototype._adjacentComponent = function (hash, depth) {
+ var hashSet = new Set();
+ hashSet.add(hash);
+ this._adjacentComponentRecursive(hashSet, [hash], 0, depth);
+ return this._setToArray(hashSet);
+ };
+ SpatialDataComponent.prototype._adjacentComponentRecursive = function (hashSet, currentHashes, currentDepth, maxDepth) {
+ if (currentDepth === maxDepth) {
+ return;
+ }
+ var neighbours = [];
+ for (var _i = 0, currentHashes_1 = currentHashes; _i < currentHashes_1.length; _i++) {
+ var hash = currentHashes_1[_i];
+ var hashNeighbours = geohash.neighbours(hash);
+ for (var direction in hashNeighbours) {
+ if (!hashNeighbours.hasOwnProperty(direction)) {
+ continue;
+ }
+ neighbours.push(hashNeighbours[direction]);
+ }
+ }
+ var newHashes = [];
+ for (var _a = 0, neighbours_1 = neighbours; _a < neighbours_1.length; _a++) {
+ var neighbour = neighbours_1[_a];
+ if (!hashSet.has(neighbour)) {
+ hashSet.add(neighbour);
+ newHashes.push(neighbour);
+ }
+ }
+ this._adjacentComponentRecursive(hashSet, newHashes, currentDepth + 1, maxDepth);
+ };
+ SpatialDataComponent.prototype._computeOriginalPosition = function (data, reference) {
+ return this._geoCoords.geodeticToEnu(data.originalLat, data.originalLon, data.alt, reference.lat, reference.lon, reference.alt);
+ };
+ SpatialDataComponent.prototype._computeTileBBox = function (hash, reference) {
+ var bounds = geohash.bounds(hash);
+ var sw = this._geoCoords.geodeticToEnu(bounds.sw.lat, bounds.sw.lon, 0, reference.lat, reference.lon, reference.alt);
+ var ne = this._geoCoords.geodeticToEnu(bounds.ne.lat, bounds.ne.lon, 0, reference.lat, reference.lon, reference.alt);
+ return [sw, ne];
+ };
+ SpatialDataComponent.prototype._createTransform = function (data, reference) {
+ var translation = Geo_1.Geo.computeTranslation({ alt: data.alt, lat: data.lat, lon: data.lon }, data.rotation, reference);
+ var transform = new Geo_1.Transform(data.orientation, data.width, data.height, data.focal, data.scale, data.gpano, data.rotation, translation, undefined, undefined, data.k1, data.k2, data.cameraProjection);
+ return transform;
+ };
+ SpatialDataComponent.prototype._computeTiles = function (hash, direction) {
+ var hashSet = new Set();
+ var directions = ["n", "ne", "e", "se", "s", "sw", "w", "nw"];
+ this._computeTilesRecursive(hashSet, hash, direction, directions, 0, 2);
+ return this._setToArray(hashSet);
+ };
+ SpatialDataComponent.prototype._computeTilesRecursive = function (hashSet, currentHash, direction, directions, currentDepth, maxDepth) {
+ hashSet.add(currentHash);
+ if (currentDepth === maxDepth) {
+ return;
+ }
+ var neighbours = geohash.neighbours(currentHash);
+ var directionIndex = directions.indexOf(direction);
+ var length = directions.length;
+ var directionNeighbours = [
+ neighbours[directions[this._modulo((directionIndex - 1), length)]],
+ neighbours[direction],
+ neighbours[directions[this._modulo((directionIndex + 1), length)]],
+ ];
+ for (var _i = 0, directionNeighbours_1 = directionNeighbours; _i < directionNeighbours_1.length; _i++) {
+ var directionNeighbour = directionNeighbours_1[_i];
+ this._computeTilesRecursive(hashSet, directionNeighbour, direction, directions, currentDepth + 1, maxDepth);
+ }
+ };
+ SpatialDataComponent.prototype._modulo = function (a, n) {
+ return ((a % n) + n) % n;
+ };
+ SpatialDataComponent.prototype._setToArray = function (s) {
+ var a = [];
+ s.forEach(function (value) {
+ a.push(value);
+ });
+ return a;
+ };
+ SpatialDataComponent.componentName = "spatialData";
+ return SpatialDataComponent;
+}(Component_1.Component));
+exports.SpatialDataComponent = SpatialDataComponent;
+Component_1.ComponentService.register(SpatialDataComponent);
+exports.default = SpatialDataComponent;
+
+},{"../../Component":275,"../../Geo":278,"../../Render":281,"../../state/State":413,"../../viewer/PlayService":443,"latlon-geohash":21,"rxjs":27,"rxjs/operators":225}],342:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var SpatialDataScene = /** @class */ (function () {
+ function SpatialDataScene(configuration, scene, raycaster) {
+ this._scene = !!scene ? scene : new THREE.Scene();
+ this._raycaster = !!raycaster ? raycaster : new THREE.Raycaster(undefined, undefined, 0.8);
+ this._connectedComponentColors = {};
+ this._needsRender = false;
+ this._interactiveObjects = [];
+ this._reconstructions = {};
+ this._tiles = {};
+ this._camerasVisible = configuration.camerasVisible;
+ this._pointsVisible = configuration.pointsVisible;
+ this._positionsVisible = configuration.positionsVisible;
+ this._tilesVisible = configuration.tilesVisible;
+ this._visualizeConnectedComponents = configuration.connectedComponents;
+ }
+ Object.defineProperty(SpatialDataScene.prototype, "needsRender", {
+ get: function () {
+ return this._needsRender;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ SpatialDataScene.prototype.addReconstruction = function (reconstruction, transform, originalPosition, connectedComponent, hash) {
+ if (!(hash in this._reconstructions)) {
+ this._reconstructions[hash] = {
+ cameraKeys: {},
+ cameras: new THREE.Object3D(),
+ connectedComponents: {},
+ keys: [],
+ points: new THREE.Object3D(),
+ positions: new THREE.Object3D(),
+ };
+ this._reconstructions[hash].cameras.visible = this._camerasVisible;
+ this._reconstructions[hash].points.visible = this._pointsVisible;
+ this._reconstructions[hash].positions.visible = this._positionsVisible;
+ this._scene.add(this._reconstructions[hash].cameras, this._reconstructions[hash].points, this._reconstructions[hash].positions);
+ }
+ if (!(connectedComponent in this._reconstructions[hash].connectedComponents)) {
+ this._reconstructions[hash].connectedComponents[connectedComponent] = [];
+ }
+ if (transform.hasValidScale) {
+ this._reconstructions[hash].points.add(this._createPoints(reconstruction, transform));
+ }
+ var camera = this._createCamera(transform);
+ this._reconstructions[hash].cameras.add(camera);
+ for (var _i = 0, _a = camera.children; _i < _a.length; _i++) {
+ var child = _a[_i];
+ this._reconstructions[hash].cameraKeys[child.uuid] = reconstruction.main_shot;
+ this._interactiveObjects.push(child);
+ }
+ this._reconstructions[hash].connectedComponents[connectedComponent].push(camera);
+ var color = this._getColor(connectedComponent, this._visualizeConnectedComponents);
+ this._setCameraColor(color, camera);
+ this._reconstructions[hash].positions.add(this._createPosition(transform, originalPosition));
+ this._reconstructions[hash].keys.push(reconstruction.main_shot);
+ this._needsRender = true;
+ };
+ SpatialDataScene.prototype.addTile = function (tileBBox, hash) {
+ if (this.hasTile(hash)) {
+ return;
+ }
+ var sw = tileBBox[0];
+ var ne = tileBBox[1];
+ var geometry = new THREE.Geometry();
+ geometry.vertices.push(new THREE.Vector3().fromArray(sw), new THREE.Vector3(sw[0], ne[1], (sw[2] + ne[2]) / 2), new THREE.Vector3().fromArray(ne), new THREE.Vector3(ne[0], sw[1], (sw[2] + ne[2]) / 2), new THREE.Vector3().fromArray(sw));
+ var tile = new THREE.Line(geometry, new THREE.LineBasicMaterial());
+ this._tiles[hash] = new THREE.Object3D();
+ this._tiles[hash].visible = this._tilesVisible;
+ this._tiles[hash].add(tile);
+ this._scene.add(this._tiles[hash]);
+ this._needsRender = true;
+ };
+ SpatialDataScene.prototype.uncache = function (keepHashes) {
+ for (var _i = 0, _a = Object.keys(this._reconstructions); _i < _a.length; _i++) {
+ var hash = _a[_i];
+ if (!!keepHashes && keepHashes.indexOf(hash) !== -1) {
+ continue;
+ }
+ this._disposeReconstruction(hash);
+ }
+ for (var _b = 0, _c = Object.keys(this._tiles); _b < _c.length; _b++) {
+ var hash = _c[_b];
+ if (!!keepHashes && keepHashes.indexOf(hash) !== -1) {
+ continue;
+ }
+ this._disposeTile(hash);
+ }
+ this._needsRender = true;
+ };
+ SpatialDataScene.prototype.hasReconstruction = function (key, hash) {
+ return hash in this._reconstructions && this._reconstructions[hash].keys.indexOf(key) !== -1;
+ };
+ SpatialDataScene.prototype.hasTile = function (hash) {
+ return hash in this._tiles;
+ };
+ SpatialDataScene.prototype.intersectObjects = function (_a, camera) {
+ var viewportX = _a[0], viewportY = _a[1];
+ if (!this._camerasVisible) {
+ return null;
+ }
+ this._raycaster.setFromCamera(new THREE.Vector2(viewportX, viewportY), camera);
+ var intersects = this._raycaster.intersectObjects(this._interactiveObjects);
+ for (var _i = 0, intersects_1 = intersects; _i < intersects_1.length; _i++) {
+ var intersect = intersects_1[_i];
+ for (var hash in this._reconstructions) {
+ if (!this._reconstructions.hasOwnProperty(hash)) {
+ continue;
+ }
+ if (intersect.object.uuid in this._reconstructions[hash].cameraKeys) {
+ return this._reconstructions[hash].cameraKeys[intersect.object.uuid];
+ }
+ }
+ }
+ return null;
+ };
+ SpatialDataScene.prototype.setCameraVisibility = function (visible) {
+ if (visible === this._camerasVisible) {
+ return;
+ }
+ for (var hash in this._reconstructions) {
+ if (!this._reconstructions.hasOwnProperty(hash)) {
+ continue;
+ }
+ this._reconstructions[hash].cameras.visible = visible;
+ }
+ this._camerasVisible = visible;
+ this._needsRender = true;
+ };
+ SpatialDataScene.prototype.setPointVisibility = function (visible) {
+ if (visible === this._pointsVisible) {
+ return;
+ }
+ for (var hash in this._reconstructions) {
+ if (!this._reconstructions.hasOwnProperty(hash)) {
+ continue;
+ }
+ this._reconstructions[hash].points.visible = visible;
+ }
+ this._pointsVisible = visible;
+ this._needsRender = true;
+ };
+ SpatialDataScene.prototype.setPositionVisibility = function (visible) {
+ if (visible === this._positionsVisible) {
+ return;
+ }
+ for (var hash in this._reconstructions) {
+ if (!this._reconstructions.hasOwnProperty(hash)) {
+ continue;
+ }
+ this._reconstructions[hash].positions.visible = visible;
+ }
+ this._positionsVisible = visible;
+ this._needsRender = true;
+ };
+ SpatialDataScene.prototype.setTileVisibility = function (visible) {
+ if (visible === this._tilesVisible) {
+ return;
+ }
+ for (var hash in this._tiles) {
+ if (!this._tiles.hasOwnProperty(hash)) {
+ continue;
+ }
+ this._tiles[hash].visible = visible;
+ }
+ this._tilesVisible = visible;
+ this._needsRender = true;
+ };
+ SpatialDataScene.prototype.setConnectedComponentVisualization = function (visualize) {
+ if (visualize === this._visualizeConnectedComponents) {
+ return;
+ }
+ for (var hash in this._reconstructions) {
+ if (!this._reconstructions.hasOwnProperty(hash)) {
+ continue;
+ }
+ var connectedComponents = this._reconstructions[hash].connectedComponents;
+ for (var connectedComponent in connectedComponents) {
+ if (!connectedComponents.hasOwnProperty(connectedComponent)) {
+ continue;
+ }
+ var color = this._getColor(connectedComponent, visualize);
+ for (var _i = 0, _a = connectedComponents[connectedComponent]; _i < _a.length; _i++) {
+ var camera = _a[_i];
+ this._setCameraColor(color, camera);
+ }
+ }
+ }
+ this._visualizeConnectedComponents = visualize;
+ this._needsRender = true;
+ };
+ SpatialDataScene.prototype.render = function (perspectiveCamera, renderer) {
+ renderer.render(this._scene, perspectiveCamera);
+ this._needsRender = false;
+ };
+ SpatialDataScene.prototype._arrayToFloatArray = function (a, columns) {
+ var n = a.length;
+ var f = new Float32Array(n * columns);
+ for (var i = 0; i < n; i++) {
+ var item = a[i];
+ var index = 3 * i;
+ f[index + 0] = item[0];
+ f[index + 1] = item[1];
+ f[index + 2] = item[2];
+ }
+ return f;
+ };
+ SpatialDataScene.prototype._createAxis = function (transform) {
+ var north = transform.unprojectBasic([0.5, 0], 0.22);
+ var south = transform.unprojectBasic([0.5, 1], 0.16);
+ var axis = new THREE.BufferGeometry();
+ axis.addAttribute("position", new THREE.BufferAttribute(this._arrayToFloatArray([north, south], 3), 3));
+ return new THREE.Line(axis, new THREE.LineBasicMaterial());
+ };
+ SpatialDataScene.prototype._createCamera = function (transform) {
+ return !!transform.gpano ?
+ this._createPanoCamera(transform) :
+ this._createPrespectiveCamera(transform);
+ };
+ SpatialDataScene.prototype._createDiagonals = function (transform, depth) {
+ var origin = transform.unprojectBasic([0, 0], 0, true);
+ var topLeft = transform.unprojectBasic([0, 0], depth, true);
+ var topRight = transform.unprojectBasic([1, 0], depth, true);
+ var bottomRight = transform.unprojectBasic([1, 1], depth, true);
+ var bottomLeft = transform.unprojectBasic([0, 1], depth, true);
+ var vertices = [
+ origin, topLeft,
+ origin, topRight,
+ origin, bottomRight,
+ origin, bottomLeft,
+ ];
+ var diagonals = new THREE.BufferGeometry();
+ diagonals.addAttribute("position", new THREE.BufferAttribute(this._arrayToFloatArray(vertices, 3), 3));
+ return new THREE.LineSegments(diagonals, new THREE.LineBasicMaterial());
+ };
+ SpatialDataScene.prototype._createFrame = function (transform, depth) {
+ var vertices2d = [];
+ vertices2d.push.apply(vertices2d, this._subsample([0, 1], [0, 0], 20));
+ vertices2d.push.apply(vertices2d, this._subsample([0, 0], [1, 0], 20));
+ vertices2d.push.apply(vertices2d, this._subsample([1, 0], [1, 1], 20));
+ var vertices3d = vertices2d
+ .map(function (basic) {
+ return transform.unprojectBasic(basic, depth, true);
+ });
+ var frame = new THREE.BufferGeometry();
+ frame.addAttribute("position", new THREE.BufferAttribute(this._arrayToFloatArray(vertices3d, 3), 3));
+ return new THREE.Line(frame, new THREE.LineBasicMaterial());
+ };
+ SpatialDataScene.prototype._createLatitude = function (basicY, numVertices, transform) {
+ var positions = new Float32Array((numVertices + 1) * 3);
+ for (var i = 0; i <= numVertices; i++) {
+ var position = transform.unprojectBasic([i / numVertices, basicY], 0.16);
+ var index = 3 * i;
+ positions[index + 0] = position[0];
+ positions[index + 1] = position[1];
+ positions[index + 2] = position[2];
+ }
+ var latitude = new THREE.BufferGeometry();
+ latitude.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+ return new THREE.Line(latitude, new THREE.LineBasicMaterial());
+ };
+ SpatialDataScene.prototype._createLongitude = function (basicX, numVertices, transform) {
+ var positions = new Float32Array((numVertices + 1) * 3);
+ for (var i = 0; i <= numVertices; i++) {
+ var position = transform.unprojectBasic([basicX, i / numVertices], 0.16);
+ var index = 3 * i;
+ positions[index + 0] = position[0];
+ positions[index + 1] = position[1];
+ positions[index + 2] = position[2];
+ }
+ var latitude = new THREE.BufferGeometry();
+ latitude.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+ return new THREE.Line(latitude, new THREE.LineBasicMaterial());
+ };
+ SpatialDataScene.prototype._createPanoCamera = function (transform) {
+ var camera = new THREE.Object3D();
+ camera.children.push(this._createAxis(transform));
+ camera.children.push(this._createLatitude(0.5, 10, transform));
+ camera.children.push(this._createLongitude(0, 6, transform));
+ camera.children.push(this._createLongitude(0.25, 6, transform));
+ camera.children.push(this._createLongitude(0.5, 6, transform));
+ camera.children.push(this._createLongitude(0.75, 6, transform));
+ return camera;
+ };
+ SpatialDataScene.prototype._createPoints = function (reconstruction, transform) {
+ var srtInverse = new THREE.Matrix4().getInverse(transform.srt);
+ var points = Object
+ .keys(reconstruction.points)
+ .map(function (key) {
+ return reconstruction.points[key];
+ });
+ var numPoints = points.length;
+ var positions = new Float32Array(numPoints * 3);
+ var colors = new Float32Array(numPoints * 3);
+ for (var i = 0; i < numPoints; i++) {
+ var index = 3 * i;
+ var coords = points[i].coordinates;
+ var point = new THREE.Vector3(coords[0], coords[1], coords[2])
+ .applyMatrix4(srtInverse);
+ positions[index + 0] = point.x;
+ positions[index + 1] = point.y;
+ positions[index + 2] = point.z;
+ var color = points[i].color;
+ colors[index + 0] = color[0] / 255.0;
+ colors[index + 1] = color[1] / 255.0;
+ colors[index + 2] = color[2] / 255.0;
+ }
+ var geometry = new THREE.BufferGeometry();
+ geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+ geometry.addAttribute("color", new THREE.BufferAttribute(colors, 3));
+ var material = new THREE.PointsMaterial({
+ size: 0.1,
+ vertexColors: THREE.VertexColors,
+ });
+ return new THREE.Points(geometry, material);
+ };
+ SpatialDataScene.prototype._createPosition = function (transform, originalPosition) {
+ var computedPosition = transform.unprojectBasic([0, 0], 0);
+ var vertices = [originalPosition, computedPosition];
+ var geometry = new THREE.BufferGeometry();
+ geometry.addAttribute("position", new THREE.BufferAttribute(this._arrayToFloatArray(vertices, 3), 3));
+ return new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: new THREE.Color(1, 0, 0) }));
+ };
+ SpatialDataScene.prototype._createPrespectiveCamera = function (transform) {
+ var depth = 0.2;
+ var camera = new THREE.Object3D();
+ camera.children.push(this._createDiagonals(transform, depth));
+ camera.children.push(this._createFrame(transform, depth));
+ return camera;
+ };
+ SpatialDataScene.prototype._disposeCameras = function (hash) {
+ var tileCameras = this._reconstructions[hash].cameras;
+ for (var _i = 0, _a = tileCameras.children.slice(); _i < _a.length; _i++) {
+ var camera = _a[_i];
+ for (var _b = 0, _c = camera.children; _b < _c.length; _b++) {
+ var child = _c[_b];
+ child.geometry.dispose();
+ child.material.dispose();
+ var index = this._interactiveObjects.indexOf(child);
+ if (index !== -1) {
+ this._interactiveObjects.splice(index, 1);
+ }
+ else {
+ console.warn("Object does not exist (" + child.id + ") for " + hash);
+ }
+ }
+ tileCameras.remove(camera);
+ }
+ this._scene.remove(tileCameras);
+ };
+ SpatialDataScene.prototype._disposePoints = function (hash) {
+ var tilePoints = this._reconstructions[hash].points;
+ for (var _i = 0, _a = tilePoints.children.slice(); _i < _a.length; _i++) {
+ var points = _a[_i];
+ points.geometry.dispose();
+ points.material.dispose();
+ tilePoints.remove(points);
+ }
+ this._scene.remove(tilePoints);
+ };
+ SpatialDataScene.prototype._disposePositions = function (hash) {
+ var tilePositions = this._reconstructions[hash].positions;
+ for (var _i = 0, _a = tilePositions.children.slice(); _i < _a.length; _i++) {
+ var position = _a[_i];
+ position.geometry.dispose();
+ position.material.dispose();
+ tilePositions.remove(position);
+ }
+ this._scene.remove(tilePositions);
+ };
+ SpatialDataScene.prototype._disposeReconstruction = function (hash) {
+ this._disposeCameras(hash);
+ this._disposePoints(hash);
+ this._disposePositions(hash);
+ delete this._reconstructions[hash];
+ };
+ SpatialDataScene.prototype._disposeTile = function (hash) {
+ var tile = this._tiles[hash];
+ for (var _i = 0, _a = tile.children.slice(); _i < _a.length; _i++) {
+ var line = _a[_i];
+ line.geometry.dispose();
+ line.material.dispose();
+ tile.remove(line);
+ }
+ this._scene.remove(tile);
+ delete this._tiles[hash];
+ };
+ SpatialDataScene.prototype._getColor = function (connectedComponent, visualizeConnectedComponents) {
+ return visualizeConnectedComponents ?
+ this._getConnectedComponentColor(connectedComponent) :
+ "#FFFFFF";
+ };
+ SpatialDataScene.prototype._getConnectedComponentColor = function (connectedComponent) {
+ if (!(connectedComponent in this._connectedComponentColors)) {
+ this._connectedComponentColors[connectedComponent] = this._randomColor();
+ }
+ return this._connectedComponentColors[connectedComponent];
+ };
+ SpatialDataScene.prototype._interpolate = function (a, b, alpha) {
+ return a + alpha * (b - a);
+ };
+ SpatialDataScene.prototype._randomColor = function () {
+ return "hsl(" + Math.floor(360 * Math.random()) + ", 100%, 65%)";
+ };
+ SpatialDataScene.prototype._setCameraColor = function (color, camera) {
+ for (var _i = 0, _a = camera.children; _i < _a.length; _i++) {
+ var child = _a[_i];
+ child.material.color = new THREE.Color(color);
+ }
+ };
+ SpatialDataScene.prototype._subsample = function (p1, p2, subsamples) {
+ if (subsamples < 1) {
+ return [p1, p2];
+ }
+ var samples = [];
+ for (var i = 0; i <= subsamples + 1; i++) {
+ var p = [];
+ for (var j = 0; j < 3; j++) {
+ p.push(this._interpolate(p1[j], p2[j], i / (subsamples + 1)));
+ }
+ samples.push(p);
+ }
+ return samples;
+ };
+ return SpatialDataScene;
+}());
+exports.SpatialDataScene = SpatialDataScene;
+exports.default = SpatialDataScene;
+
+},{"three":226}],343:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var GeometryTagError_1 = require("./error/GeometryTagError");
+exports.GeometryTagError = GeometryTagError_1.GeometryTagError;
+var PointGeometry_1 = require("./geometry/PointGeometry");
+exports.PointGeometry = PointGeometry_1.PointGeometry;
+var RectGeometry_1 = require("./geometry/RectGeometry");
+exports.RectGeometry = RectGeometry_1.RectGeometry;
+var PolygonGeometry_1 = require("./geometry/PolygonGeometry");
+exports.PolygonGeometry = PolygonGeometry_1.PolygonGeometry;
+var OutlineTag_1 = require("./tag/OutlineTag");
+exports.OutlineTag = OutlineTag_1.OutlineTag;
+var SpotTag_1 = require("./tag/SpotTag");
+exports.SpotTag = SpotTag_1.SpotTag;
+var TagDomain_1 = require("./tag/TagDomain");
+exports.TagDomain = TagDomain_1.TagDomain;
+var TagComponent_1 = require("./TagComponent");
+exports.TagComponent = TagComponent_1.TagComponent;
+var TagMode_1 = require("./TagMode");
+exports.TagMode = TagMode_1.TagMode;
+
+},{"./TagComponent":344,"./TagMode":347,"./error/GeometryTagError":351,"./geometry/PointGeometry":353,"./geometry/PolygonGeometry":354,"./geometry/RectGeometry":355,"./tag/OutlineTag":367,"./tag/SpotTag":370,"./tag/TagDomain":372}],344:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var when = require("when");
+var Component_1 = require("../../Component");
+var Geo_1 = require("../../Geo");
+var Render_1 = require("../../Render");
+/**
+ * @class TagComponent
+ *
+ * @classdesc Component for showing and editing tags with different
+ * geometries composed from 2D basic image coordinates (see the
+ * {@link Viewer} class documentation for more information about coordinate
+ * systems).
+ *
+ * The `add` method is used for adding new tags or replacing
+ * tags already in the set. Tags are removed by id.
+ *
+ * If a tag already in the set has the same
+ * id as one of the tags added, the old tag will be removed and
+ * the added tag will take its place.
+ *
+ * The tag component mode can be set to either be non interactive or
+ * to be in creating mode of a certain geometry type.
+ *
+ * The tag properties can be updated at any time and the change will
+ * be visibile immediately.
+ *
+ * Tags are only relevant to a single image because they are based on
+ * 2D basic image coordinates. Tags related to a certain image should
+ * be removed when the viewer is moved to another node.
+ *
+ * To retrive and use the tag component
+ *
+ * @example
+ * ```
+ * var viewer = new Mapillary.Viewer(
+ * "<element-id>",
+ * "<client-id>",
+ * "<my key>",
+ * { component: { tag: true } });
+ *
+ * var tagComponent = viewer.getComponent("tag");
+ * ```
+ */
+var TagComponent = /** @class */ (function (_super) {
+ __extends(TagComponent, _super);
+ /** @ignore */
+ function TagComponent(name, container, navigator) {
+ var _this = _super.call(this, name, container, navigator) || this;
+ _this._tagDomRenderer = new Component_1.TagDOMRenderer();
+ _this._tagScene = new Component_1.TagScene();
+ _this._tagSet = new Component_1.TagSet();
+ _this._tagCreator = new Component_1.TagCreator(_this, navigator);
+ _this._viewportCoords = new Geo_1.ViewportCoords();
+ _this._createHandlers = {
+ "CreatePoint": new Component_1.CreatePointHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
+ "CreatePolygon": new Component_1.CreatePolygonHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
+ "CreateRect": new Component_1.CreateRectHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
+ "CreateRectDrag": new Component_1.CreateRectDragHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
+ "Default": undefined,
+ };
+ _this._editVertexHandler = new Component_1.EditVertexHandler(_this, container, navigator, _this._viewportCoords, _this._tagSet);
+ _this._renderTags$ = _this._tagSet.changed$.pipe(operators_1.map(function (tagSet) {
+ var tags = tagSet.getAll();
+ // ensure that tags are always rendered in the same order
+ // to avoid hover tracking problems on first resize.
+ tags.sort(function (t1, t2) {
+ var id1 = t1.tag.id;
+ var id2 = t2.tag.id;
+ if (id1 < id2) {
+ return -1;
+ }
+ if (id1 > id2) {
+ return 1;
+ }
+ return 0;
+ });
+ return tags;
+ }), operators_1.share());
+ _this._tagChanged$ = _this._renderTags$.pipe(operators_1.switchMap(function (tags) {
+ return rxjs_1.from(tags).pipe(operators_1.mergeMap(function (tag) {
+ return rxjs_1.merge(tag.tag.changed$, tag.tag.geometryChanged$);
+ }));
+ }), operators_1.share());
+ _this._renderTagGLChanged$ = _this._renderTags$.pipe(operators_1.switchMap(function (tags) {
+ return rxjs_1.from(tags).pipe(operators_1.mergeMap(function (tag) {
+ return tag.glObjectsChanged$;
+ }));
+ }), operators_1.share());
+ _this._createGeometryChanged$ = _this._tagCreator.tag$.pipe(operators_1.switchMap(function (tag) {
+ return tag != null ?
+ tag.geometryChanged$ :
+ rxjs_1.empty();
+ }), operators_1.share());
+ _this._createGLObjectsChanged$ = _this._tagCreator.tag$.pipe(operators_1.switchMap(function (tag) {
+ return tag != null ?
+ tag.glObjectsChanged$ :
+ rxjs_1.empty();
+ }), operators_1.share());
+ _this._creatingConfiguration$ = _this._configuration$.pipe(operators_1.distinctUntilChanged(function (c1, c2) {
+ return c1.mode === c2.mode;
+ }, function (configuration) {
+ return {
+ createColor: configuration.createColor,
+ mode: configuration.mode,
+ };
+ }), operators_1.publishReplay(1), operators_1.refCount());
+ _this._creatingConfiguration$
+ .subscribe(function (configuration) {
+ _this.fire(TagComponent.modechanged, configuration.mode);
+ });
+ return _this;
+ }
+ /**
+ * Add tags to the tag set or replace tags in the tag set.
+ *
+ * @description If a tag already in the set has the same
+ * id as one of the tags added, the old tag will be removed
+ * the added tag will take its place.
+ *
+ * @param {Array<Tag>} tags - Tags to add.
+ *
+ * @example ```tagComponent.add([tag1, tag2]);```
+ */
+ TagComponent.prototype.add = function (tags) {
+ var _this = this;
+ if (this._activated) {
+ this._navigator.stateService.currentTransform$.pipe(operators_1.first())
+ .subscribe(function (transform) {
+ _this._tagSet.add(tags, transform);
+ var renderTags = tags
+ .map(function (tag) {
+ return _this._tagSet.get(tag.id);
+ });
+ _this._tagScene.add(renderTags);
+ });
+ }
+ else {
+ this._tagSet.addDeactivated(tags);
+ }
+ };
+ /**
+ * Change the current tag mode.
+ *
+ * @description Change the tag mode to one of the create modes for creating new geometries.
+ *
+ * @param {TagMode} mode - New tag mode.
+ *
+ * @fires TagComponent#modechanged
+ *
+ * @example ```tagComponent.changeMode(Mapillary.TagComponent.TagMode.CreateRect);```
+ */
+ TagComponent.prototype.changeMode = function (mode) {
+ this.configure({ mode: mode });
+ };
+ /**
+ * Returns the tag in the tag set with the specified id, or
+ * undefined if the id matches no tag.
+ *
+ * @param {string} tagId - Id of the tag.
+ *
+ * @example ```var tag = tagComponent.get("tagId");```
+ */
+ TagComponent.prototype.get = function (tagId) {
+ if (this._activated) {
+ var renderTag = this._tagSet.get(tagId);
+ return renderTag !== undefined ? renderTag.tag : undefined;
+ }
+ else {
+ return this._tagSet.getDeactivated(tagId);
+ }
+ };
+ /**
+ * Returns an array of all tags.
+ *
+ * @example ```var tags = tagComponent.getAll();```
+ */
+ TagComponent.prototype.getAll = function () {
+ if (this.activated) {
+ return this._tagSet
+ .getAll()
+ .map(function (renderTag) {
+ return renderTag.tag;
+ });
+ }
+ else {
+ return this._tagSet.getAllDeactivated();
+ }
+ };
+ /**
+ * Returns an array of tag ids for tags that contain the specified point.
+ *
+ * @description The pixel point must lie inside the polygon or rectangle
+ * of an added tag for the tag id to be returned. Tag ids for
+ * tags that do not have a fill will also be returned if the point is inside
+ * the geometry of the tag. Tags with point geometries can not be retrieved.
+ *
+ * No tag ids will be returned for polygons rendered in cropped panoramas or
+ * rectangles rendered in panoramas.
+ *
+ * Notice that the pixelPoint argument requires x, y coordinates from pixel space.
+ *
+ * With this function, you can use the coordinates provided by mouse
+ * events to get information out of the tag component.
+ *
+ * If no tag at exist the pixel point, an empty array will be returned.
+ *
+ * @param {Array<number>} pixelPoint - Pixel coordinates on the viewer element.
+ * @returns {Array<string>} Ids of the tags that contain the specified pixel point.
+ *
+ * @example
+ * ```
+ * tagComponent.getTagIdsAt([100, 100])
+ * .then((tagIds) => { console.log(tagIds); });
+ * ```
+ */
+ TagComponent.prototype.getTagIdsAt = function (pixelPoint) {
+ var _this = this;
+ return when.promise(function (resolve, reject) {
+ _this._container.renderService.renderCamera$.pipe(operators_1.first(), operators_1.map(function (render) {
+ var viewport = _this._viewportCoords
+ .canvasToViewport(pixelPoint[0], pixelPoint[1], _this._container.element);
+ var ids = _this._tagScene.intersectObjects(viewport, render.perspective);
+ return ids;
+ }))
+ .subscribe(function (ids) {
+ resolve(ids);
+ }, function (error) {
+ reject(error);
+ });
+ });
+ };
+ /**
+ * Check if a tag exist in the tag set.
+ *
+ * @param {string} tagId - Id of the tag.
+ *
+ * @example ```var tagExists = tagComponent.has("tagId");```
+ */
+ TagComponent.prototype.has = function (tagId) {
+ return this._activated ? this._tagSet.has(tagId) : this._tagSet.hasDeactivated(tagId);
+ };
+ /**
+ * Remove tags with the specified ids from the tag set.
+ *
+ * @param {Array<string>} tagIds - Ids for tags to remove.
+ *
+ * @example ```tagComponent.remove(["id-1", "id-2"]);```
+ */
+ TagComponent.prototype.remove = function (tagIds) {
+ if (this._activated) {
+ this._tagSet.remove(tagIds);
+ this._tagScene.remove(tagIds);
+ }
+ else {
+ this._tagSet.removeDeactivated(tagIds);
+ }
+ };
+ /**
+ * Remove all tags from the tag set.
+ *
+ * @example ```tagComponent.removeAll();```
+ */
+ TagComponent.prototype.removeAll = function () {
+ if (this._activated) {
+ this._tagSet.removeAll();
+ this._tagScene.removeAll();
+ }
+ else {
+ this._tagSet.removeAllDeactivated();
+ }
+ };
+ TagComponent.prototype._activate = function () {
+ var _this = this;
+ this._editVertexHandler.enable();
+ var handlerGeometryCreated$ = rxjs_1.from(Object.keys(this._createHandlers)).pipe(operators_1.map(function (key) {
+ return _this._createHandlers[key];
+ }), operators_1.filter(function (handler) {
+ return !!handler;
+ }), operators_1.mergeMap(function (handler) {
+ return handler.geometryCreated$;
+ }), operators_1.share());
+ this._fireGeometryCreatedSubscription = handlerGeometryCreated$
+ .subscribe(function (geometry) {
+ _this.fire(TagComponent.geometrycreated, geometry);
+ });
+ this._fireCreateGeometryEventSubscription = this._tagCreator.tag$.pipe(operators_1.skipWhile(function (tag) {
+ return tag == null;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (tag) {
+ var eventType = tag != null ?
+ TagComponent.creategeometrystart :
+ TagComponent.creategeometryend;
+ _this.fire(eventType, _this);
+ });
+ this._handlerStopCreateSubscription = handlerGeometryCreated$
+ .subscribe(function () {
+ _this.changeMode(Component_1.TagMode.Default);
+ });
+ this._handlerEnablerSubscription = this._creatingConfiguration$
+ .subscribe(function (configuration) {
+ _this._disableCreateHandlers();
+ var mode = Component_1.TagMode[configuration.mode];
+ var handler = _this._createHandlers[mode];
+ if (!!handler) {
+ handler.enable();
+ }
+ });
+ this._fireTagsChangedSubscription = this._renderTags$
+ .subscribe(function (tags) {
+ _this.fire(TagComponent.tagschanged, _this);
+ });
+ this._stopCreateSubscription = this._tagCreator.tag$.pipe(operators_1.switchMap(function (tag) {
+ return tag != null ?
+ tag.aborted$.pipe(operators_1.map(function (t) { return null; })) :
+ rxjs_1.empty();
+ }))
+ .subscribe(function () { _this.changeMode(Component_1.TagMode.Default); });
+ this._setGLCreateTagSubscription = this._tagCreator.tag$
+ .subscribe(function (tag) {
+ if (_this._tagScene.hasCreateTag()) {
+ _this._tagScene.removeCreateTag();
+ }
+ if (tag != null) {
+ _this._tagScene.addCreateTag(tag);
+ }
+ });
+ this._createGLObjectsChangedSubscription = this._createGLObjectsChanged$
+ .subscribe(function (tag) {
+ _this._tagScene.updateCreateTagObjects(tag);
+ });
+ this._updateGLObjectsSubscription = this._renderTagGLChanged$
+ .subscribe(function (tag) {
+ _this._tagScene.updateObjects(tag);
+ });
+ this._updateTagSceneSubscription = this._tagChanged$
+ .subscribe(function (tag) {
+ _this._tagScene.update();
+ });
+ this._domSubscription = rxjs_1.combineLatest(this._renderTags$.pipe(operators_1.startWith([]), operators_1.tap(function (tags) {
+ _this._container.domRenderer.render$.next({
+ name: _this._name,
+ vnode: _this._tagDomRenderer.clear(),
+ });
+ })), this._container.renderService.renderCamera$, this._container.spriteService.spriteAtlas$, this._container.renderService.size$, this._tagChanged$.pipe(operators_1.startWith(null)), rxjs_1.merge(this._tagCreator.tag$, this._createGeometryChanged$).pipe(operators_1.startWith(null))).pipe(operators_1.map(function (_a) {
+ var renderTags = _a[0], rc = _a[1], atlas = _a[2], size = _a[3], tag = _a[4], ct = _a[5];
+ return {
+ name: _this._name,
+ vnode: _this._tagDomRenderer.render(renderTags, ct, atlas, rc.perspective, size),
+ };
+ }))
+ .subscribe(this._container.domRenderer.render$);
+ this._glSubscription = this._navigator.stateService.currentState$.pipe(operators_1.map(function (frame) {
+ var tagScene = _this._tagScene;
+ return {
+ name: _this._name,
+ render: {
+ frameId: frame.id,
+ needsRender: tagScene.needsRender,
+ render: tagScene.render.bind(tagScene),
+ stage: Render_1.GLRenderStage.Foreground,
+ },
+ };
+ }))
+ .subscribe(this._container.glRenderer.render$);
+ this._navigator.stateService.currentTransform$.pipe(operators_1.first())
+ .subscribe(function (transform) {
+ _this._tagSet.activate(transform);
+ _this._tagScene.add(_this._tagSet.getAll());
+ });
+ };
+ TagComponent.prototype._deactivate = function () {
+ this._editVertexHandler.disable();
+ this._disableCreateHandlers();
+ this._tagScene.clear();
+ this._tagSet.deactivate();
+ this._tagCreator.delete$.next(null);
+ this._updateGLObjectsSubscription.unsubscribe();
+ this._updateTagSceneSubscription.unsubscribe();
+ this._stopCreateSubscription.unsubscribe();
+ this._setGLCreateTagSubscription.unsubscribe();
+ this._createGLObjectsChangedSubscription.unsubscribe();
+ this._domSubscription.unsubscribe();
+ this._glSubscription.unsubscribe();
+ this._fireCreateGeometryEventSubscription.unsubscribe();
+ this._fireGeometryCreatedSubscription.unsubscribe();
+ this._fireTagsChangedSubscription.unsubscribe();
+ this._handlerStopCreateSubscription.unsubscribe();
+ this._handlerEnablerSubscription.unsubscribe();
+ this._container.element.classList.remove("component-tag-create");
+ };
+ TagComponent.prototype._getDefaultConfiguration = function () {
+ return {
+ createColor: 0xFFFFFF,
+ mode: Component_1.TagMode.Default,
+ };
+ };
+ TagComponent.prototype._disableCreateHandlers = function () {
+ var createHandlers = this._createHandlers;
+ for (var key in createHandlers) {
+ if (!createHandlers.hasOwnProperty(key)) {
+ continue;
+ }
+ var handler = createHandlers[key];
+ if (!!handler) {
+ handler.disable();
+ }
+ }
+ };
+ /** @inheritdoc */
+ TagComponent.componentName = "tag";
+ /**
+ * Event fired when an interaction to create a geometry ends.
+ *
+ * @description A create interaction can by a geometry being created
+ * or by the creation being aborted.
+ *
+ * @event TagComponent#creategeometryend
+ * @type {TagComponent} Tag component.
+ * @example
+ * ```
+ * tagComponent.on("creategeometryend", function(component) {
+ * console.log(component);
+ * });
+ * ```
+ */
+ TagComponent.creategeometryend = "creategeometryend";
+ /**
+ * Event fired when an interaction to create a geometry starts.
+ *
+ * @description A create interaction starts when the first vertex
+ * is created in the geometry.
+ *
+ * @event TagComponent#creategeometrystart
+ * @type {TagComponent} Tag component.
+ * @example
+ * ```
+ * tagComponent.on("creategeometrystart", function(component) {
+ * console.log(component);
+ * });
+ * ```
+ */
+ TagComponent.creategeometrystart = "creategeometrystart";
+ /**
+ * Event fired when the create mode is changed.
+ *
+ * @event TagComponent#modechanged
+ * @type {TagMode} Tag mode
+ * @example
+ * ```
+ * tagComponent.on("modechanged", function(mode) {
+ * console.log(mode);
+ * });
+ * ```
+ */
+ TagComponent.modechanged = "modechanged";
+ /**
+ * Event fired when a geometry has been created.
+ *
+ * @event TagComponent#geometrycreated
+ * @type {Geometry} Created geometry.
+ * @example
+ * ```
+ * tagComponent.on("geometrycreated", function(geometry) {
+ * console.log(geometry);
+ * });
+ * ```
+ */
+ TagComponent.geometrycreated = "geometrycreated";
+ /**
+ * Event fired when the tags collection has changed.
+ *
+ * @event TagComponent#tagschanged
+ * @type {TagComponent} Tag component.
+ * @example
+ * ```
+ * tagComponent.on("tagschanged", function(component) {
+ * console.log(component.getAll());
+ * });
+ * ```
+ */
+ TagComponent.tagschanged = "tagschanged";
+ return TagComponent;
+}(Component_1.Component));
+exports.TagComponent = TagComponent;
+Component_1.ComponentService.register(TagComponent);
+exports.default = TagComponent;
+
+},{"../../Component":275,"../../Geo":278,"../../Render":281,"rxjs":27,"rxjs/operators":225,"when":272}],345:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var rxjs_1 = require("rxjs");
+var Component_1 = require("../../Component");
+var TagCreator = /** @class */ (function () {
+ function TagCreator(component, navigator) {
+ this._component = component;
+ this._navigator = navigator;
+ this._tagOperation$ = new rxjs_1.Subject();
+ this._createPolygon$ = new rxjs_1.Subject();
+ this._createRect$ = new rxjs_1.Subject();
+ this._delete$ = new rxjs_1.Subject();
+ this._tag$ = this._tagOperation$.pipe(operators_1.scan(function (tag, operation) {
+ return operation(tag);
+ }, null), operators_1.share());
+ this._createRect$.pipe(operators_1.withLatestFrom(this._component.configuration$, this._navigator.stateService.currentTransform$), operators_1.map(function (_a) {
+ var coord = _a[0], conf = _a[1], transform = _a[2];
+ return function (tag) {
+ var geometry = new Component_1.RectGeometry([
+ coord[0],
+ coord[1],
+ coord[0],
+ coord[1],
+ ]);
+ return new Component_1.OutlineCreateTag(geometry, { color: conf.createColor }, transform);
+ };
+ }))
+ .subscribe(this._tagOperation$);
+ this._createPolygon$.pipe(operators_1.withLatestFrom(this._component.configuration$, this._navigator.stateService.currentTransform$), operators_1.map(function (_a) {
+ var coord = _a[0], conf = _a[1], transform = _a[2];
+ return function (tag) {
+ var geometry = new Component_1.PolygonGeometry([
+ [coord[0], coord[1]],
+ [coord[0], coord[1]],
+ [coord[0], coord[1]],
+ ]);
+ return new Component_1.OutlineCreateTag(geometry, { color: conf.createColor }, transform);
+ };
+ }))
+ .subscribe(this._tagOperation$);
+ this._delete$.pipe(operators_1.map(function () {
+ return function (tag) {
+ return null;
+ };
+ }))
+ .subscribe(this._tagOperation$);
+ }
+ Object.defineProperty(TagCreator.prototype, "createRect$", {
+ get: function () {
+ return this._createRect$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(TagCreator.prototype, "createPolygon$", {
+ get: function () {
+ return this._createPolygon$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(TagCreator.prototype, "delete$", {
+ get: function () {
+ return this._delete$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(TagCreator.prototype, "tag$", {
+ get: function () {
+ return this._tag$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return TagCreator;
+}());
+exports.TagCreator = TagCreator;
+exports.default = TagCreator;
+
+},{"../../Component":275,"rxjs":27,"rxjs/operators":225}],346:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var vd = require("virtual-dom");
+var TagDOMRenderer = /** @class */ (function () {
+ function TagDOMRenderer() {
+ }
+ TagDOMRenderer.prototype.render = function (tags, createTag, atlas, camera, size) {
+ var vNodes = [];
+ for (var _i = 0, tags_1 = tags; _i < tags_1.length; _i++) {
+ var tag = tags_1[_i];
+ vNodes = vNodes.concat(tag.getDOMObjects(atlas, camera, size));
+ }
+ if (createTag != null) {
+ vNodes = vNodes.concat(createTag.getDOMObjects(camera, size));
+ }
+ return vd.h("div.TagContainer", {}, vNodes);
+ };
+ TagDOMRenderer.prototype.clear = function () {
+ return vd.h("div", {}, []);
+ };
+ return TagDOMRenderer;
+}());
+exports.TagDOMRenderer = TagDOMRenderer;
+
+},{"virtual-dom":231}],347:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * Enumeration for tag modes
+ * @enum {number}
+ * @readonly
+ * @description Modes for the interaction in the tag component.
+ */
+var TagMode;
+(function (TagMode) {
+ /**
+ * Disables creating tags.
+ */
+ TagMode[TagMode["Default"] = 0] = "Default";
+ /**
+ * Create a point geometry through a click.
+ */
+ TagMode[TagMode["CreatePoint"] = 1] = "CreatePoint";
+ /**
+ * Create a polygon geometry through clicks.
+ */
+ TagMode[TagMode["CreatePolygon"] = 2] = "CreatePolygon";
+ /**
+ * Create a rect geometry through clicks.
+ */
+ TagMode[TagMode["CreateRect"] = 3] = "CreateRect";
+ /**
+ * Create a rect geometry through drag.
+ *
+ * @description Claims the mouse which results in mouse handlers like
+ * drag pan and scroll zoom becoming inactive.
+ */
+ TagMode[TagMode["CreateRectDrag"] = 4] = "CreateRectDrag";
+})(TagMode = exports.TagMode || (exports.TagMode = {}));
+exports.default = TagMode;
+
+},{}],348:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var TagOperation;
+(function (TagOperation) {
+ TagOperation[TagOperation["None"] = 0] = "None";
+ TagOperation[TagOperation["Centroid"] = 1] = "Centroid";
+ TagOperation[TagOperation["Vertex"] = 2] = "Vertex";
+})(TagOperation = exports.TagOperation || (exports.TagOperation = {}));
+exports.default = TagOperation;
+
+},{}],349:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var TagScene = /** @class */ (function () {
+ function TagScene(scene, raycaster) {
+ this._createTag = null;
+ this._needsRender = false;
+ this._raycaster = !!raycaster ? raycaster : new THREE.Raycaster();
+ this._scene = !!scene ? scene : new THREE.Scene();
+ this._objectTags = {};
+ this._retrievableObjects = [];
+ this._tags = {};
+ }
+ Object.defineProperty(TagScene.prototype, "needsRender", {
+ get: function () {
+ return this._needsRender;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ TagScene.prototype.add = function (tags) {
+ for (var _i = 0, tags_1 = tags; _i < tags_1.length; _i++) {
+ var tag = tags_1[_i];
+ if (tag.tag.id in this._tags) {
+ this._remove(tag.tag.id);
+ }
+ this._add(tag);
+ }
+ this._needsRender = true;
+ };
+ TagScene.prototype.addCreateTag = function (tag) {
+ for (var _i = 0, _a = tag.glObjects; _i < _a.length; _i++) {
+ var object = _a[_i];
+ this._scene.add(object);
+ }
+ this._createTag = { tag: tag, objects: tag.glObjects };
+ this._needsRender = true;
+ };
+ TagScene.prototype.clear = function () {
+ for (var _i = 0, _a = Object.keys(this._tags); _i < _a.length; _i++) {
+ var id = _a[_i];
+ this._remove(id);
+ }
+ this._needsRender = false;
+ };
+ TagScene.prototype.get = function (id) {
+ return this.has(id) ? this._tags[id].tag : undefined;
+ };
+ TagScene.prototype.has = function (id) {
+ return id in this._tags;
+ };
+ TagScene.prototype.hasCreateTag = function () {
+ return this._createTag != null;
+ };
+ TagScene.prototype.intersectObjects = function (_a, camera) {
+ var viewportX = _a[0], viewportY = _a[1];
+ this._raycaster.setFromCamera(new THREE.Vector2(viewportX, viewportY), camera);
+ var intersects = this._raycaster.intersectObjects(this._retrievableObjects);
+ var intersectedIds = [];
+ for (var _i = 0, intersects_1 = intersects; _i < intersects_1.length; _i++) {
+ var intersect = intersects_1[_i];
+ if (intersect.object.uuid in this._objectTags) {
+ intersectedIds.push(this._objectTags[intersect.object.uuid]);
+ }
+ }
+ return intersectedIds;
+ };
+ TagScene.prototype.remove = function (ids) {
+ for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
+ var id = ids_1[_i];
+ this._remove(id);
+ }
+ this._needsRender = true;
+ };
+ TagScene.prototype.removeAll = function () {
+ for (var _i = 0, _a = Object.keys(this._tags); _i < _a.length; _i++) {
+ var id = _a[_i];
+ this._remove(id);
+ }
+ this._needsRender = true;
+ };
+ TagScene.prototype.removeCreateTag = function () {
+ if (this._createTag == null) {
+ return;
+ }
+ for (var _i = 0, _a = this._createTag.objects; _i < _a.length; _i++) {
+ var object = _a[_i];
+ this._scene.remove(object);
+ }
+ this._createTag.tag.dispose();
+ this._createTag = null;
+ this._needsRender = true;
+ };
+ TagScene.prototype.render = function (perspectiveCamera, renderer) {
+ renderer.render(this._scene, perspectiveCamera);
+ this._needsRender = false;
+ };
+ TagScene.prototype.update = function () {
+ this._needsRender = true;
+ };
+ TagScene.prototype.updateCreateTagObjects = function (tag) {
+ if (this._createTag.tag !== tag) {
+ throw new Error("Create tags do not have the same reference.");
+ }
+ for (var _i = 0, _a = this._createTag.objects; _i < _a.length; _i++) {
+ var object = _a[_i];
+ this._scene.remove(object);
+ }
+ for (var _b = 0, _c = tag.glObjects; _b < _c.length; _b++) {
+ var object = _c[_b];
+ this._scene.add(object);
+ }
+ this._createTag.objects = tag.glObjects;
+ this._needsRender = true;
+ };
+ TagScene.prototype.updateObjects = function (tag) {
+ var id = tag.tag.id;
+ if (this._tags[id].tag !== tag) {
+ throw new Error("Tags do not have the same reference.");
+ }
+ var tagObjects = this._tags[id];
+ this._removeObjects(tagObjects);
+ delete this._tags[id];
+ this._add(tag);
+ this._needsRender = true;
+ };
+ TagScene.prototype._add = function (tag) {
+ var id = tag.tag.id;
+ var tagObjects = { tag: tag, objects: [], retrievableObjects: [] };
+ this._tags[id] = tagObjects;
+ for (var _i = 0, _a = tag.getGLObjects(); _i < _a.length; _i++) {
+ var object = _a[_i];
+ tagObjects.objects.push(object);
+ this._scene.add(object);
+ }
+ for (var _b = 0, _c = tag.getRetrievableObjects(); _b < _c.length; _b++) {
+ var retrievableObject = _c[_b];
+ tagObjects.retrievableObjects.push(retrievableObject);
+ this._retrievableObjects.push(retrievableObject);
+ this._objectTags[retrievableObject.uuid] = tag.tag.id;
+ }
+ };
+ TagScene.prototype._remove = function (id) {
+ var tagObjects = this._tags[id];
+ this._removeObjects(tagObjects);
+ tagObjects.tag.dispose();
+ delete this._tags[id];
+ };
+ TagScene.prototype._removeObjects = function (tagObjects) {
+ for (var _i = 0, _a = tagObjects.objects; _i < _a.length; _i++) {
+ var object = _a[_i];
+ this._scene.remove(object);
+ }
+ for (var _b = 0, _c = tagObjects.retrievableObjects; _b < _c.length; _b++) {
+ var retrievableObject = _c[_b];
+ var index = this._retrievableObjects.indexOf(retrievableObject);
+ if (index !== -1) {
+ this._retrievableObjects.splice(index, 1);
+ }
+ }
+ };
+ return TagScene;
+}());
+exports.TagScene = TagScene;
+exports.default = TagScene;
+
+},{"three":226}],350:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var Component_1 = require("../../Component");
+var TagSet = /** @class */ (function () {
+ function TagSet() {
+ this._active = false;
+ this._hash = {};
+ this._hashDeactivated = {};
+ this._notifyChanged$ = new rxjs_1.Subject();
+ }
+ Object.defineProperty(TagSet.prototype, "active", {
+ get: function () {
+ return this._active;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(TagSet.prototype, "changed$", {
+ get: function () {
+ return this._notifyChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ TagSet.prototype.activate = function (transform) {
+ if (this._active) {
+ return;
+ }
+ for (var id in this._hashDeactivated) {
+ if (!this._hashDeactivated.hasOwnProperty(id)) {
+ continue;
+ }
+ var tag = this._hashDeactivated[id];
+ this._add(tag, transform);
+ }
+ this._hashDeactivated = {};
+ this._active = true;
+ this._notifyChanged$.next(this);
+ };
+ TagSet.prototype.deactivate = function () {
+ if (!this._active) {
+ return;
+ }
+ for (var id in this._hash) {
+ if (!this._hash.hasOwnProperty(id)) {
+ continue;
+ }
+ this._hashDeactivated[id] = this._hash[id].tag;
+ }
+ this._hash = {};
+ this._active = false;
+ };
+ TagSet.prototype.add = function (tags, transform) {
+ this._assertActivationState(true);
+ for (var _i = 0, tags_1 = tags; _i < tags_1.length; _i++) {
+ var tag = tags_1[_i];
+ this._add(tag, transform);
+ }
+ this._notifyChanged$.next(this);
+ };
+ TagSet.prototype.addDeactivated = function (tags) {
+ this._assertActivationState(false);
+ for (var _i = 0, tags_2 = tags; _i < tags_2.length; _i++) {
+ var tag = tags_2[_i];
+ if (!(tag instanceof Component_1.OutlineTag || tag instanceof Component_1.SpotTag)) {
+ throw new Error("Tag type not supported");
+ }
+ this._hashDeactivated[tag.id] = tag;
+ }
+ };
+ TagSet.prototype.get = function (id) {
+ return this.has(id) ? this._hash[id] : undefined;
+ };
+ TagSet.prototype.getAll = function () {
+ var hash = this._hash;
+ return Object.keys(hash)
+ .map(function (id) {
+ return hash[id];
+ });
+ };
+ TagSet.prototype.getAllDeactivated = function () {
+ var hashDeactivated = this._hashDeactivated;
+ return Object.keys(hashDeactivated)
+ .map(function (id) {
+ return hashDeactivated[id];
+ });
+ };
+ TagSet.prototype.getDeactivated = function (id) {
+ return this.hasDeactivated(id) ? this._hashDeactivated[id] : undefined;
+ };
+ TagSet.prototype.has = function (id) {
+ return id in this._hash;
+ };
+ TagSet.prototype.hasDeactivated = function (id) {
+ return id in this._hashDeactivated;
+ };
+ TagSet.prototype.remove = function (ids) {
+ this._assertActivationState(true);
+ var hash = this._hash;
+ for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
+ var id = ids_1[_i];
+ if (!(id in hash)) {
+ continue;
+ }
+ delete hash[id];
+ }
+ this._notifyChanged$.next(this);
+ };
+ TagSet.prototype.removeAll = function () {
+ this._assertActivationState(true);
+ this._hash = {};
+ this._notifyChanged$.next(this);
+ };
+ TagSet.prototype.removeAllDeactivated = function () {
+ this._assertActivationState(false);
+ this._hashDeactivated = {};
+ };
+ TagSet.prototype.removeDeactivated = function (ids) {
+ this._assertActivationState(false);
+ var hashDeactivated = this._hashDeactivated;
+ for (var _i = 0, ids_2 = ids; _i < ids_2.length; _i++) {
+ var id = ids_2[_i];
+ if (!(id in hashDeactivated)) {
+ continue;
+ }
+ delete hashDeactivated[id];
+ }
+ };
+ TagSet.prototype._add = function (tag, transform) {
+ if (tag instanceof Component_1.OutlineTag) {
+ this._hash[tag.id] = new Component_1.OutlineRenderTag(tag, transform);
+ }
+ else if (tag instanceof Component_1.SpotTag) {
+ this._hash[tag.id] = new Component_1.SpotRenderTag(tag, transform);
+ }
+ else {
+ throw new Error("Tag type not supported");
+ }
+ };
+ TagSet.prototype._assertActivationState = function (should) {
+ if (should !== this._active) {
+ throw new Error("Tag set not in correct state for operation.");
+ }
+ };
+ return TagSet;
+}());
+exports.TagSet = TagSet;
+exports.default = TagSet;
+
+},{"../../Component":275,"rxjs":27}],351:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Error_1 = require("../../../Error");
+var GeometryTagError = /** @class */ (function (_super) {
+ __extends(GeometryTagError, _super);
+ function GeometryTagError(message) {
+ var _this = _super.call(this, message != null ? message : "The provided geometry value is incorrect") || this;
+ _this.name = "GeometryTagError";
+ return _this;
+ }
+ return GeometryTagError;
+}(Error_1.MapillaryError));
+exports.GeometryTagError = GeometryTagError;
+exports.default = Error_1.MapillaryError;
+
+},{"../../../Error":277}],352:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+/**
+ * @class Geometry
+ * @abstract
+ * @classdesc Represents a geometry.
+ */
+var Geometry = /** @class */ (function () {
+ /**
+ * Create a geometry.
+ *
+ * @constructor
+ * @ignore
+ */
+ function Geometry() {
+ this._notifyChanged$ = new rxjs_1.Subject();
+ }
+ Object.defineProperty(Geometry.prototype, "changed$", {
+ /**
+ * Get changed observable.
+ *
+ * @description Emits the geometry itself every time the geometry
+ * has changed.
+ *
+ * @returns {Observable<Geometry>} Observable emitting the geometry instance.
+ * @ignore
+ */
+ get: function () {
+ return this._notifyChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return Geometry;
+}());
+exports.Geometry = Geometry;
+exports.default = Geometry;
+
+},{"rxjs":27}],353:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../../Component");
+/**
+ * @class PointGeometry
+ *
+ * @classdesc Represents a point geometry in the 2D basic image coordinate system.
+ *
+ * @example
+ * ```
+ * var basicPoint = [0.5, 0.7];
+ * var pointGeometry = new Mapillary.TagComponent.PointGeometry(basicPoint);
+ * ```
+ */
+var PointGeometry = /** @class */ (function (_super) {
+ __extends(PointGeometry, _super);
+ /**
+ * Create a point geometry.
+ *
+ * @constructor
+ * @param {Array<number>} point - An array representing the basic coordinates of
+ * the point.
+ *
+ * @throws {GeometryTagError} Point coordinates must be valid basic coordinates.
+ */
+ function PointGeometry(point) {
+ var _this = _super.call(this) || this;
+ var x = point[0];
+ var y = point[1];
+ if (x < 0 || x > 1 || y < 0 || y > 1) {
+ throw new Component_1.GeometryTagError("Basic coordinates must be on the interval [0, 1].");
+ }
+ _this._point = point.slice();
+ return _this;
+ }
+ Object.defineProperty(PointGeometry.prototype, "point", {
+ /**
+ * Get point property.
+ * @returns {Array<number>} Array representing the basic coordinates of the point.
+ */
+ get: function () {
+ return this._point;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Get the 2D basic coordinates for the centroid of the point, i.e. the 2D
+ * basic coordinates of the point itself.
+ *
+ * @returns {Array<number>} 2D basic coordinates representing the centroid.
+ * @ignore
+ */
+ PointGeometry.prototype.getCentroid2d = function () {
+ return this._point.slice();
+ };
+ /**
+ * Get the 3D world coordinates for the centroid of the point, i.e. the 3D
+ * world coordinates of the point itself.
+ *
+ * @param {Transform} transform - The transform of the node related to the point.
+ * @returns {Array<number>} 3D world coordinates representing the centroid.
+ * @ignore
+ */
+ PointGeometry.prototype.getCentroid3d = function (transform) {
+ return transform.unprojectBasic(this._point, 200);
+ };
+ /**
+ * Set the centroid of the point, i.e. the point coordinates.
+ *
+ * @param {Array<number>} value - The new value of the centroid.
+ * @param {Transform} transform - The transform of the node related to the point.
+ * @ignore
+ */
+ PointGeometry.prototype.setCentroid2d = function (value, transform) {
+ var changed = [
+ Math.max(0, Math.min(1, value[0])),
+ Math.max(0, Math.min(1, value[1])),
+ ];
+ this._point[0] = changed[0];
+ this._point[1] = changed[1];
+ this._notifyChanged$.next(this);
+ };
+ return PointGeometry;
+}(Component_1.Geometry));
+exports.PointGeometry = PointGeometry;
+
+},{"../../../Component":275}],354:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../../Component");
+/**
+ * @class PolygonGeometry
+ *
+ * @classdesc Represents a polygon geometry in the 2D basic image coordinate system.
+ * All polygons and holes provided to the constructor needs to be closed.
+ *
+ * @example
+ * ```
+ * var basicPolygon = [[0.5, 0.3], [0.7, 0.3], [0.6, 0.5], [0.5, 0.3]];
+ * var polygonGeometry = new Mapillary.TagComponent.PolygonGeometry(basicPolygon);
+ * ```
+ */
+var PolygonGeometry = /** @class */ (function (_super) {
+ __extends(PolygonGeometry, _super);
+ /**
+ * Create a polygon geometry.
+ *
+ * @constructor
+ * @param {Array<Array<number>>} polygon - Array of polygon vertices. Must be closed.
+ * @param {Array<Array<Array<number>>>} [holes] - Array of arrays of hole vertices.
+ * Each array of holes vertices must be closed.
+ *
+ * @throws {GeometryTagError} Polygon coordinates must be valid basic coordinates.
+ */
+ function PolygonGeometry(polygon, holes) {
+ var _this = _super.call(this) || this;
+ var polygonLength = polygon.length;
+ if (polygonLength < 3) {
+ throw new Component_1.GeometryTagError("A polygon must have three or more positions.");
+ }
+ if (polygon[0][0] !== polygon[polygonLength - 1][0] ||
+ polygon[0][1] !== polygon[polygonLength - 1][1]) {
+ throw new Component_1.GeometryTagError("First and last positions must be equivalent.");
+ }
+ _this._polygon = [];
+ for (var _i = 0, polygon_1 = polygon; _i < polygon_1.length; _i++) {
+ var vertex = polygon_1[_i];
+ if (vertex[0] < 0 || vertex[0] > 1 ||
+ vertex[1] < 0 || vertex[1] > 1) {
+ throw new Component_1.GeometryTagError("Basic coordinates of polygon must be on the interval [0, 1].");
+ }
+ _this._polygon.push(vertex.slice());
+ }
+ _this._holes = [];
+ if (holes == null) {
+ return _this;
+ }
+ for (var i = 0; i < holes.length; i++) {
+ var hole = holes[i];
+ var holeLength = hole.length;
+ if (holeLength < 3) {
+ throw new Component_1.GeometryTagError("A polygon hole must have three or more positions.");
+ }
+ if (hole[0][0] !== hole[holeLength - 1][0] ||
+ hole[0][1] !== hole[holeLength - 1][1]) {
+ throw new Component_1.GeometryTagError("First and last positions of hole must be equivalent.");
+ }
+ _this._holes.push([]);
+ for (var _a = 0, hole_1 = hole; _a < hole_1.length; _a++) {
+ var vertex = hole_1[_a];
+ if (vertex[0] < 0 || vertex[0] > 1 ||
+ vertex[1] < 0 || vertex[1] > 1) {
+ throw new Component_1.GeometryTagError("Basic coordinates of hole must be on the interval [0, 1].");
+ }
+ _this._holes[i].push(vertex.slice());
+ }
+ }
+ return _this;
+ }
+ Object.defineProperty(PolygonGeometry.prototype, "polygon", {
+ /**
+ * Get polygon property.
+ * @returns {Array<Array<number>>} Closed 2d polygon.
+ */
+ get: function () {
+ return this._polygon;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(PolygonGeometry.prototype, "holes", {
+ /**
+ * Get holes property.
+ * @returns {Array<Array<Array<number>>>} Holes of 2d polygon.
+ */
+ get: function () {
+ return this._holes;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Add a vertex to the polygon by appending it after the last vertex.
+ *
+ * @param {Array<number>} vertex - Vertex to add.
+ * @ignore
+ */
+ PolygonGeometry.prototype.addVertex2d = function (vertex) {
+ var clamped = [
+ Math.max(0, Math.min(1, vertex[0])),
+ Math.max(0, Math.min(1, vertex[1])),
+ ];
+ this._polygon.splice(this._polygon.length - 1, 0, clamped);
+ this._notifyChanged$.next(this);
+ };
+ /**
+ * Get the coordinates of a vertex from the polygon representation of the geometry.
+ *
+ * @description The first vertex represents the bottom-left corner with the rest of
+ * the vertices following in clockwise order.
+ *
+ * @param {number} index - Vertex index.
+ * @returns {Array<number>} Array representing the 2D basic coordinates of the vertex.
+ * @ignore
+ */
+ PolygonGeometry.prototype.getVertex2d = function (index) {
+ return this._polygon[index].slice();
+ };
+ /**
+ * Remove a vertex from the polygon.
+ *
+ * @param {number} index - The index of the vertex to remove.
+ * @ignore
+ */
+ PolygonGeometry.prototype.removeVertex2d = function (index) {
+ if (index < 0 ||
+ index >= this._polygon.length ||
+ this._polygon.length < 4) {
+ throw new Component_1.GeometryTagError("Index for removed vertex must be valid.");
+ }
+ if (index > 0 && index < this._polygon.length - 1) {
+ this._polygon.splice(index, 1);
+ }
+ else {
+ this._polygon.splice(0, 1);
+ this._polygon.pop();
+ var closing = this._polygon[0].slice();
+ this._polygon.push(closing);
+ }
+ this._notifyChanged$.next(this);
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.setVertex2d = function (index, value, transform) {
+ var changed = [
+ Math.max(0, Math.min(1, value[0])),
+ Math.max(0, Math.min(1, value[1])),
+ ];
+ if (index === 0 || index === this._polygon.length - 1) {
+ this._polygon[0] = changed.slice();
+ this._polygon[this._polygon.length - 1] = changed.slice();
+ }
+ else {
+ this._polygon[index] = changed.slice();
+ }
+ this._notifyChanged$.next(this);
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.setCentroid2d = function (value, transform) {
+ var xs = this._polygon.map(function (point) { return point[0]; });
+ var ys = this._polygon.map(function (point) { return point[1]; });
+ var minX = Math.min.apply(Math, xs);
+ var maxX = Math.max.apply(Math, xs);
+ var minY = Math.min.apply(Math, ys);
+ var maxY = Math.max.apply(Math, ys);
+ var centroid = this.getCentroid2d();
+ var minTranslationX = -minX;
+ var maxTranslationX = 1 - maxX;
+ var minTranslationY = -minY;
+ var maxTranslationY = 1 - maxY;
+ var translationX = Math.max(minTranslationX, Math.min(maxTranslationX, value[0] - centroid[0]));
+ var translationY = Math.max(minTranslationY, Math.min(maxTranslationY, value[1] - centroid[1]));
+ for (var _i = 0, _a = this._polygon; _i < _a.length; _i++) {
+ var point = _a[_i];
+ point[0] += translationX;
+ point[1] += translationY;
+ }
+ this._notifyChanged$.next(this);
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.getPoints3d = function (transform) {
+ return this._getPoints3d(this._subsample(this._polygon), transform);
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.getVertex3d = function (index, transform) {
+ return transform.unprojectBasic(this._polygon[index], 200);
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.getVertices2d = function () {
+ return this._polygon.slice();
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.getVertices3d = function (transform) {
+ return this._getPoints3d(this._polygon, transform);
+ };
+ /**
+ * Get a polygon representation of the 3D coordinates for the vertices of each hole
+ * of the geometry. Line segments between vertices will possibly be subsampled
+ * resulting in a larger number of points than the total number of vertices.
+ *
+ * @param {Transform} transform - The transform of the node related to the geometry.
+ * @returns {Array<Array<Array<number>>>} Array of hole polygons in 3D world coordinates
+ * representing the vertices of each hole of the geometry.
+ * @ignore
+ */
+ PolygonGeometry.prototype.getHolePoints3d = function (transform) {
+ var _this = this;
+ return this._holes
+ .map(function (hole2d) {
+ return _this._getPoints3d(_this._subsample(hole2d), transform);
+ });
+ };
+ /**
+ * Get a polygon representation of the 3D coordinates for the vertices of each hole
+ * of the geometry.
+ *
+ * @param {Transform} transform - The transform of the node related to the geometry.
+ * @returns {Array<Array<Array<number>>>} Array of hole polygons in 3D world coordinates
+ * representing the vertices of each hole of the geometry.
+ * @ignore
+ */
+ PolygonGeometry.prototype.getHoleVertices3d = function (transform) {
+ var _this = this;
+ return this._holes
+ .map(function (hole2d) {
+ return _this._getPoints3d(hole2d, transform);
+ });
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.getCentroid2d = function () {
+ var polygon = this._polygon;
+ var area = 0;
+ var centroidX = 0;
+ var centroidY = 0;
+ for (var i = 0; i < polygon.length - 1; i++) {
+ var xi = polygon[i][0];
+ var yi = polygon[i][1];
+ var xi1 = polygon[i + 1][0];
+ var yi1 = polygon[i + 1][1];
+ var a = xi * yi1 - xi1 * yi;
+ area += a;
+ centroidX += (xi + xi1) * a;
+ centroidY += (yi + yi1) * a;
+ }
+ area /= 2;
+ centroidX /= 6 * area;
+ centroidY /= 6 * area;
+ return [centroidX, centroidY];
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.getCentroid3d = function (transform) {
+ var centroid2d = this.getCentroid2d();
+ return transform.unprojectBasic(centroid2d, 200);
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.get3dDomainTriangles3d = function (transform) {
+ var _this = this;
+ return this._triangulate(this._project(this._polygon, transform), this.getVertices3d(transform), this._holes
+ .map(function (hole2d) {
+ return _this._project(hole2d, transform);
+ }), this.getHoleVertices3d(transform));
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.getTriangles3d = function (transform) {
+ var _this = this;
+ if (transform.fullPano) {
+ return this._triangulatePano(this._polygon.slice(), this.holes.slice(), transform);
+ }
+ var points2d = this._project(this._subsample(this._polygon), transform);
+ var points3d = this.getPoints3d(transform);
+ var holes2d = this._holes
+ .map(function (hole) {
+ return _this._project(_this._subsample(hole), transform);
+ });
+ var holes3d = this.getHolePoints3d(transform);
+ return this._triangulate(points2d, points3d, holes2d, holes3d);
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.getPoleOfInaccessibility2d = function () {
+ return this._getPoleOfInaccessibility2d(this._polygon.slice());
+ };
+ /** @ignore */
+ PolygonGeometry.prototype.getPoleOfInaccessibility3d = function (transform) {
+ var pole2d = this._getPoleOfInaccessibility2d(this._polygon.slice());
+ return transform.unprojectBasic(pole2d, 200);
+ };
+ PolygonGeometry.prototype._getPoints3d = function (points2d, transform) {
+ return points2d
+ .map(function (point) {
+ return transform.unprojectBasic(point, 200);
+ });
+ };
+ return PolygonGeometry;
+}(Component_1.VertexGeometry));
+exports.PolygonGeometry = PolygonGeometry;
+exports.default = PolygonGeometry;
+
+},{"../../../Component":275}],355:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../../Component");
+/**
+ * @class RectGeometry
+ *
+ * @classdesc Represents a rectangle geometry in the 2D basic image coordinate system.
+ *
+ * @example
+ * ```
+ * var basicRect = [0.5, 0.3, 0.7, 0.4];
+ * var rectGeometry = new Mapillary.TagComponent.RectGeometry(basicRect);
+ * ```
+ */
+var RectGeometry = /** @class */ (function (_super) {
+ __extends(RectGeometry, _super);
+ /**
+ * Create a rectangle geometry.
+ *
+ * @constructor
+ * @param {Array<number>} rect - An array representing the top-left and bottom-right
+ * corners of the rectangle in basic coordinates. Ordered according to [x0, y0, x1, y1].
+ *
+ * @throws {GeometryTagError} Rectangle coordinates must be valid basic coordinates.
+ */
+ function RectGeometry(rect) {
+ var _this = _super.call(this) || this;
+ if (rect[1] > rect[3]) {
+ throw new Component_1.GeometryTagError("Basic Y coordinates values can not be inverted.");
+ }
+ for (var _i = 0, rect_1 = rect; _i < rect_1.length; _i++) {
+ var coord = rect_1[_i];
+ if (coord < 0 || coord > 1) {
+ throw new Component_1.GeometryTagError("Basic coordinates must be on the interval [0, 1].");
+ }
+ }
+ _this._anchorIndex = undefined;
+ _this._rect = rect.slice(0, 4);
+ _this._inverted = _this._rect[0] > _this._rect[2];
+ return _this;
+ }
+ Object.defineProperty(RectGeometry.prototype, "anchorIndex", {
+ /**
+ * Get anchor index property.
+ *
+ * @returns {number} Index representing the current anchor property if
+ * achoring indexing has been initialized. If anchor indexing has not been
+ * initialized or has been terminated undefined will be returned.
+ * @ignore
+ */
+ get: function () {
+ return this._anchorIndex;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(RectGeometry.prototype, "inverted", {
+ /**
+ * Get inverted property.
+ *
+ * @returns {boolean} Boolean determining whether the rect geometry is
+ * inverted. For panoramas the rect geometrye may be inverted.
+ * @ignore
+ */
+ get: function () {
+ return this._inverted;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(RectGeometry.prototype, "rect", {
+ /**
+ * Get rect property.
+ *
+ * @returns {Array<number>} Array representing the top-left and bottom-right
+ * corners of the rectangle in basic coordinates.
+ */
+ get: function () {
+ return this._rect;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ /**
+ * Initialize anchor indexing to enable setting opposite vertex.
+ *
+ * @param {number} [index] - The index of the vertex to use as anchor.
+ *
+ * @throws {Error} If anchor indexing has already been initialized.
+ * @throws {Error} If index is not valid (0 to 3).
+ * @ignore
+ */
+ RectGeometry.prototype.initializeAnchorIndexing = function (index) {
+ if (this._anchorIndex !== undefined) {
+ throw new Error("Anchor indexing is already initialized.");
+ }
+ if (index < 0 || index > 3) {
+ throw new Error("Invalid anchor index: " + index + ".");
+ }
+ this._anchorIndex = index === undefined ? 0 : index;
+ };
+ /**
+ * Terminate anchor indexing to disable setting pposite vertex.
+ * @ignore
+ */
+ RectGeometry.prototype.terminateAnchorIndexing = function () {
+ this._anchorIndex = undefined;
+ };
+ /**
+ * Set the value of the vertex opposite to the anchor in the polygon
+ * representation of the rectangle.
+ *
+ * @description Setting the opposite vertex may change the anchor index.
+ *
+ * @param {Array<number>} opposite - The new value of the vertex opposite to the anchor.
+ * @param {Transform} transform - The transform of the node related to the rectangle.
+ *
+ * @throws {Error} When anchor indexing has not been initialized.
+ * @ignore
+ */
+ RectGeometry.prototype.setOppositeVertex2d = function (opposite, transform) {
+ if (this._anchorIndex === undefined) {
+ throw new Error("Anchor indexing needs to be initialized.");
+ }
+ var changed = [
+ Math.max(0, Math.min(1, opposite[0])),
+ Math.max(0, Math.min(1, opposite[1])),
+ ];
+ var original = this._rect.slice();
+ var anchor = this._anchorIndex === 0 ? [original[0], original[3]] :
+ this._anchorIndex === 1 ? [original[0], original[1]] :
+ this._anchorIndex === 2 ? [original[2], original[1]] :
+ [original[2], original[3]];
+ if (transform.fullPano) {
+ var deltaX = this._anchorIndex < 2 ?
+ changed[0] - original[2] :
+ changed[0] - original[0];
+ if (!this._inverted && this._anchorIndex < 2 && changed[0] < 0.25 && original[2] > 0.75 && deltaX < -0.5) {
+ // right side passes boundary rightward
+ this._inverted = true;
+ this._anchorIndex = anchor[1] > changed[1] ? 0 : 1;
+ }
+ else if (!this._inverted && this._anchorIndex >= 2 && changed[0] < 0.25 && original[2] > 0.75 && deltaX < -0.5) {
+ // left side passes right side and boundary rightward
+ this._inverted = true;
+ this._anchorIndex = anchor[1] > changed[1] ? 0 : 1;
+ }
+ else if (this._inverted && this._anchorIndex >= 2 && changed[0] < 0.25 && original[0] > 0.75 && deltaX < -0.5) {
+ this._inverted = false;
+ if (anchor[0] > changed[0]) {
+ // left side passes boundary rightward
+ this._anchorIndex = anchor[1] > changed[1] ? 3 : 2;
+ }
+ else {
+ // left side passes right side and boundary rightward
+ this._anchorIndex = anchor[1] > changed[1] ? 0 : 1;
+ }
+ }
+ else if (!this._inverted && this._anchorIndex >= 2 && changed[0] > 0.75 && original[0] < 0.25 && deltaX > 0.5) {
+ // left side passes boundary leftward
+ this._inverted = true;
+ this._anchorIndex = anchor[1] > changed[1] ? 3 : 2;
+ }
+ else if (!this._inverted && this._anchorIndex < 2 && changed[0] > 0.75 && original[0] < 0.25 && deltaX > 0.5) {
+ // right side passes left side and boundary leftward
+ this._inverted = true;
+ this._anchorIndex = anchor[1] > changed[1] ? 3 : 2;
+ }
+ else if (this._inverted && this._anchorIndex < 2 && changed[0] > 0.75 && original[2] < 0.25 && deltaX > 0.5) {
+ this._inverted = false;
+ if (anchor[0] > changed[0]) {
+ // right side passes boundary leftward
+ this._anchorIndex = anchor[1] > changed[1] ? 3 : 2;
+ }
+ else {
+ // right side passes left side and boundary leftward
+ this._anchorIndex = anchor[1] > changed[1] ? 0 : 1;
+ }
+ }
+ else if (this._inverted && this._anchorIndex < 2 && changed[0] > original[0]) {
+ // inverted and right side passes left side completing a loop
+ this._inverted = false;
+ this._anchorIndex = anchor[1] > changed[1] ? 0 : 1;
+ }
+ else if (this._inverted && this._anchorIndex >= 2 && changed[0] < original[2]) {
+ // inverted and left side passes right side completing a loop
+ this._inverted = false;
+ this._anchorIndex = anchor[1] > changed[1] ? 3 : 2;
+ }
+ else if (this._inverted) {
+ // if still inverted only top and bottom can switch
+ if (this._anchorIndex < 2) {
+ this._anchorIndex = anchor[1] > changed[1] ? 0 : 1;
+ }
+ else {
+ this._anchorIndex = anchor[1] > changed[1] ? 3 : 2;
+ }
+ }
+ else {
+ // if still not inverted treat as non full pano
+ if (anchor[0] <= changed[0] && anchor[1] > changed[1]) {
+ this._anchorIndex = 0;
+ }
+ else if (anchor[0] <= changed[0] && anchor[1] <= changed[1]) {
+ this._anchorIndex = 1;
+ }
+ else if (anchor[0] > changed[0] && anchor[1] <= changed[1]) {
+ this._anchorIndex = 2;
+ }
+ else {
+ this._anchorIndex = 3;
+ }
+ }
+ var rect = [];
+ if (this._anchorIndex === 0) {
+ rect[0] = anchor[0];
+ rect[1] = changed[1];
+ rect[2] = changed[0];
+ rect[3] = anchor[1];
+ }
+ else if (this._anchorIndex === 1) {
+ rect[0] = anchor[0];
+ rect[1] = anchor[1];
+ rect[2] = changed[0];
+ rect[3] = changed[1];
+ }
+ else if (this._anchorIndex === 2) {
+ rect[0] = changed[0];
+ rect[1] = anchor[1];
+ rect[2] = anchor[0];
+ rect[3] = changed[1];
+ }
+ else {
+ rect[0] = changed[0];
+ rect[1] = changed[1];
+ rect[2] = anchor[0];
+ rect[3] = anchor[1];
+ }
+ if (!this._inverted && rect[0] > rect[2] ||
+ this._inverted && rect[0] < rect[2]) {
+ rect[0] = original[0];
+ rect[2] = original[2];
+ }
+ if (rect[1] > rect[3]) {
+ rect[1] = original[1];
+ rect[3] = original[3];
+ }
+ this._rect[0] = rect[0];
+ this._rect[1] = rect[1];
+ this._rect[2] = rect[2];
+ this._rect[3] = rect[3];
+ }
+ else {
+ if (anchor[0] <= changed[0] && anchor[1] > changed[1]) {
+ this._anchorIndex = 0;
+ }
+ else if (anchor[0] <= changed[0] && anchor[1] <= changed[1]) {
+ this._anchorIndex = 1;
+ }
+ else if (anchor[0] > changed[0] && anchor[1] <= changed[1]) {
+ this._anchorIndex = 2;
+ }
+ else {
+ this._anchorIndex = 3;
+ }
+ var rect = [];
+ if (this._anchorIndex === 0) {
+ rect[0] = anchor[0];
+ rect[1] = changed[1];
+ rect[2] = changed[0];
+ rect[3] = anchor[1];
+ }
+ else if (this._anchorIndex === 1) {
+ rect[0] = anchor[0];
+ rect[1] = anchor[1];
+ rect[2] = changed[0];
+ rect[3] = changed[1];
+ }
+ else if (this._anchorIndex === 2) {
+ rect[0] = changed[0];
+ rect[1] = anchor[1];
+ rect[2] = anchor[0];
+ rect[3] = changed[1];
+ }
+ else {
+ rect[0] = changed[0];
+ rect[1] = changed[1];
+ rect[2] = anchor[0];
+ rect[3] = anchor[1];
+ }
+ if (rect[0] > rect[2]) {
+ rect[0] = original[0];
+ rect[2] = original[2];
+ }
+ if (rect[1] > rect[3]) {
+ rect[1] = original[1];
+ rect[3] = original[3];
+ }
+ this._rect[0] = rect[0];
+ this._rect[1] = rect[1];
+ this._rect[2] = rect[2];
+ this._rect[3] = rect[3];
+ }
+ this._notifyChanged$.next(this);
+ };
+ /**
+ * Set the value of a vertex in the polygon representation of the rectangle.
+ *
+ * @description The polygon is defined to have the first vertex at the
+ * bottom-left corner with the rest of the vertices following in clockwise order.
+ *
+ * @param {number} index - The index of the vertex to be set.
+ * @param {Array<number>} value - The new value of the vertex.
+ * @param {Transform} transform - The transform of the node related to the rectangle.
+ * @ignore
+ */
+ RectGeometry.prototype.setVertex2d = function (index, value, transform) {
+ var original = this._rect.slice();
+ var changed = [
+ Math.max(0, Math.min(1, value[0])),
+ Math.max(0, Math.min(1, value[1])),
+ ];
+ var rect = [];
+ if (index === 0) {
+ rect[0] = changed[0];
+ rect[1] = original[1];
+ rect[2] = original[2];
+ rect[3] = changed[1];
+ }
+ else if (index === 1) {
+ rect[0] = changed[0];
+ rect[1] = changed[1];
+ rect[2] = original[2];
+ rect[3] = original[3];
+ }
+ else if (index === 2) {
+ rect[0] = original[0];
+ rect[1] = changed[1];
+ rect[2] = changed[0];
+ rect[3] = original[3];
+ }
+ else if (index === 3) {
+ rect[0] = original[0];
+ rect[1] = original[1];
+ rect[2] = changed[0];
+ rect[3] = changed[1];
+ }
+ if (transform.fullPano) {
+ var passingBoundaryLeftward = index < 2 && changed[0] > 0.75 && original[0] < 0.25 ||
+ index >= 2 && this._inverted && changed[0] > 0.75 && original[2] < 0.25;
+ var passingBoundaryRightward = index < 2 && this._inverted && changed[0] < 0.25 && original[0] > 0.75 ||
+ index >= 2 && changed[0] < 0.25 && original[2] > 0.75;
+ if (passingBoundaryLeftward || passingBoundaryRightward) {
+ this._inverted = !this._inverted;
+ }
+ else {
+ if (rect[0] - original[0] < -0.25) {
+ rect[0] = original[0];
+ }
+ if (rect[2] - original[2] > 0.25) {
+ rect[2] = original[2];
+ }
+ }
+ if (!this._inverted && rect[0] > rect[2] ||
+ this._inverted && rect[0] < rect[2]) {
+ rect[0] = original[0];
+ rect[2] = original[2];
+ }
+ }
+ else {
+ if (rect[0] > rect[2]) {
+ rect[0] = original[0];
+ rect[2] = original[2];
+ }
+ }
+ if (rect[1] > rect[3]) {
+ rect[1] = original[1];
+ rect[3] = original[3];
+ }
+ this._rect[0] = rect[0];
+ this._rect[1] = rect[1];
+ this._rect[2] = rect[2];
+ this._rect[3] = rect[3];
+ this._notifyChanged$.next(this);
+ };
+ /** @ignore */
+ RectGeometry.prototype.setCentroid2d = function (value, transform) {
+ var original = this._rect.slice();
+ var x0 = original[0];
+ var x1 = this._inverted ? original[2] + 1 : original[2];
+ var y0 = original[1];
+ var y1 = original[3];
+ var centerX = x0 + (x1 - x0) / 2;
+ var centerY = y0 + (y1 - y0) / 2;
+ var translationX = 0;
+ if (transform.gpano != null &&
+ transform.gpano.CroppedAreaImageWidthPixels === transform.gpano.FullPanoWidthPixels) {
+ translationX = this._inverted ? value[0] + 1 - centerX : value[0] - centerX;
+ }
+ else {
+ var minTranslationX = -x0;
+ var maxTranslationX = 1 - x1;
+ translationX = Math.max(minTranslationX, Math.min(maxTranslationX, value[0] - centerX));
+ }
+ var minTranslationY = -y0;
+ var maxTranslationY = 1 - y1;
+ var translationY = Math.max(minTranslationY, Math.min(maxTranslationY, value[1] - centerY));
+ this._rect[0] = original[0] + translationX;
+ this._rect[1] = original[1] + translationY;
+ this._rect[2] = original[2] + translationX;
+ this._rect[3] = original[3] + translationY;
+ if (this._rect[0] < 0) {
+ this._rect[0] += 1;
+ this._inverted = !this._inverted;
+ }
+ else if (this._rect[0] > 1) {
+ this._rect[0] -= 1;
+ this._inverted = !this._inverted;
+ }
+ if (this._rect[2] < 0) {
+ this._rect[2] += 1;
+ this._inverted = !this._inverted;
+ }
+ else if (this._rect[2] > 1) {
+ this._rect[2] -= 1;
+ this._inverted = !this._inverted;
+ }
+ this._notifyChanged$.next(this);
+ };
+ /**
+ * Get the 3D coordinates for the vertices of the rectangle with
+ * interpolated points along the lines.
+ *
+ * @param {Transform} transform - The transform of the node related to
+ * the rectangle.
+ * @returns {Array<Array<number>>} Polygon array of 3D world coordinates
+ * representing the rectangle.
+ * @ignore
+ */
+ RectGeometry.prototype.getPoints3d = function (transform) {
+ return this._getPoints2d()
+ .map(function (point) {
+ return transform.unprojectBasic(point, 200);
+ });
+ };
+ /**
+ * Get the coordinates of a vertex from the polygon representation of the geometry.
+ *
+ * @description The first vertex represents the bottom-left corner with the rest of
+ * the vertices following in clockwise order. The method shifts the right side
+ * coordinates of the rectangle by one unit to ensure that the vertices are ordered
+ * clockwise.
+ *
+ * @param {number} index - Vertex index.
+ * @returns {Array<number>} Array representing the 2D basic coordinates of the vertex.
+ * @ignore
+ */
+ RectGeometry.prototype.getVertex2d = function (index) {
+ return this._rectToVertices2d(this._rect)[index];
+ };
+ /**
+ * Get the coordinates of a vertex from the polygon representation of the geometry.
+ *
+ * @description The first vertex represents the bottom-left corner with the rest of
+ * the vertices following in clockwise order. The coordinates will not be shifted
+ * so they may not appear in clockwise order when layed out on the plane.
+ *
+ * @param {number} index - Vertex index.
+ * @returns {Array<number>} Array representing the 2D basic coordinates of the vertex.
+ * @ignore
+ */
+ RectGeometry.prototype.getNonAdjustedVertex2d = function (index) {
+ return this._rectToNonAdjustedVertices2d(this._rect)[index];
+ };
+ /**
+ * Get a vertex from the polygon representation of the 3D coordinates for the
+ * vertices of the geometry.
+ *
+ * @description The first vertex represents the bottom-left corner with the rest of
+ * the vertices following in clockwise order.
+ *
+ * @param {number} index - Vertex index.
+ * @param {Transform} transform - The transform of the node related to the geometry.
+ * @returns {Array<Array<number>>} Polygon array of 3D world coordinates representing
+ * the vertices of the geometry.
+ * @ignore
+ */
+ RectGeometry.prototype.getVertex3d = function (index, transform) {
+ return transform.unprojectBasic(this._rectToVertices2d(this._rect)[index], 200);
+ };
+ /**
+ * Get a polygon representation of the 2D basic coordinates for the vertices of the rectangle.
+ *
+ * @description The first vertex represents the bottom-left corner with the rest of
+ * the vertices following in clockwise order.
+ *
+ * @returns {Array<Array<number>>} Polygon array of 2D basic coordinates representing
+ * the rectangle vertices.
+ * @ignore
+ */
+ RectGeometry.prototype.getVertices2d = function () {
+ return this._rectToVertices2d(this._rect);
+ };
+ /**
+ * Get a polygon representation of the 3D coordinates for the vertices of the rectangle.
+ *
+ * @description The first vertex represents the bottom-left corner with the rest of
+ * the vertices following in clockwise order.
+ *
+ * @param {Transform} transform - The transform of the node related to the rectangle.
+ * @returns {Array<Array<number>>} Polygon array of 3D world coordinates representing
+ * the rectangle vertices.
+ * @ignore
+ */
+ RectGeometry.prototype.getVertices3d = function (transform) {
+ return this._rectToVertices2d(this._rect)
+ .map(function (vertex) {
+ return transform.unprojectBasic(vertex, 200);
+ });
+ };
+ /** @ignore */
+ RectGeometry.prototype.getCentroid2d = function () {
+ var rect = this._rect;
+ var x0 = rect[0];
+ var x1 = this._inverted ? rect[2] + 1 : rect[2];
+ var y0 = rect[1];
+ var y1 = rect[3];
+ var centroidX = (x0 + x1) / 2;
+ var centroidY = (y0 + y1) / 2;
+ return [centroidX, centroidY];
+ };
+ /** @ignore */
+ RectGeometry.prototype.getCentroid3d = function (transform) {
+ var centroid2d = this.getCentroid2d();
+ return transform.unprojectBasic(centroid2d, 200);
+ };
+ /**
+ * @ignore
+ */
+ RectGeometry.prototype.getPoleOfInaccessibility2d = function () {
+ return this._getPoleOfInaccessibility2d(this._rectToVertices2d(this._rect));
+ };
+ /** @ignore */
+ RectGeometry.prototype.getPoleOfInaccessibility3d = function (transform) {
+ var pole2d = this._getPoleOfInaccessibility2d(this._rectToVertices2d(this._rect));
+ return transform.unprojectBasic(pole2d, 200);
+ };
+ /** @ignore */
+ RectGeometry.prototype.getTriangles3d = function (transform) {
+ return transform.fullPano ?
+ [] :
+ this._triangulate(this._project(this._getPoints2d(), transform), this.getPoints3d(transform));
+ };
+ /**
+ * Check if a particular bottom-right value is valid according to the current
+ * rectangle coordinates.
+ *
+ * @param {Array<number>} bottomRight - The bottom-right coordinates to validate
+ * @returns {boolean} Value indicating whether the provided bottom-right coordinates
+ * are valid.
+ * @ignore
+ */
+ RectGeometry.prototype.validate = function (bottomRight) {
+ var rect = this._rect;
+ if (!this._inverted && bottomRight[0] < rect[0] ||
+ bottomRight[0] - rect[2] > 0.25 ||
+ bottomRight[1] < rect[1]) {
+ return false;
+ }
+ return true;
+ };
+ /**
+ * Get the 2D coordinates for the vertices of the rectangle with
+ * interpolated points along the lines.
+ *
+ * @returns {Array<Array<number>>} Polygon array of 2D basic coordinates
+ * representing the rectangle.
+ */
+ RectGeometry.prototype._getPoints2d = function () {
+ var vertices2d = this._rectToVertices2d(this._rect);
+ var sides = vertices2d.length - 1;
+ var sections = 10;
+ var points2d = [];
+ for (var i = 0; i < sides; ++i) {
+ var startX = vertices2d[i][0];
+ var startY = vertices2d[i][1];
+ var endX = vertices2d[i + 1][0];
+ var endY = vertices2d[i + 1][1];
+ var intervalX = (endX - startX) / (sections - 1);
+ var intervalY = (endY - startY) / (sections - 1);
+ for (var j = 0; j < sections; ++j) {
+ var point = [
+ startX + j * intervalX,
+ startY + j * intervalY,
+ ];
+ points2d.push(point);
+ }
+ }
+ return points2d;
+ };
+ /**
+ * Convert the top-left, bottom-right representation of a rectangle to a polygon
+ * representation of the vertices starting at the bottom-left corner going
+ * clockwise.
+ *
+ * @description The method shifts the right side coordinates of the rectangle
+ * by one unit to ensure that the vertices are ordered clockwise.
+ *
+ * @param {Array<number>} rect - Top-left, bottom-right representation of a
+ * rectangle.
+ * @returns {Array<Array<number>>} Polygon representation of the vertices of the
+ * rectangle.
+ */
+ RectGeometry.prototype._rectToVertices2d = function (rect) {
+ return [
+ [rect[0], rect[3]],
+ [rect[0], rect[1]],
+ [this._inverted ? rect[2] + 1 : rect[2], rect[1]],
+ [this._inverted ? rect[2] + 1 : rect[2], rect[3]],
+ [rect[0], rect[3]],
+ ];
+ };
+ /**
+ * Convert the top-left, bottom-right representation of a rectangle to a polygon
+ * representation of the vertices starting at the bottom-left corner going
+ * clockwise.
+ *
+ * @description The first vertex represents the bottom-left corner with the rest of
+ * the vertices following in clockwise order. The coordinates will not be shifted
+ * to ensure that the vertices are ordered clockwise when layed out on the plane.
+ *
+ * @param {Array<number>} rect - Top-left, bottom-right representation of a
+ * rectangle.
+ * @returns {Array<Array<number>>} Polygon representation of the vertices of the
+ * rectangle.
+ */
+ RectGeometry.prototype._rectToNonAdjustedVertices2d = function (rect) {
+ return [
+ [rect[0], rect[3]],
+ [rect[0], rect[1]],
+ [rect[2], rect[1]],
+ [rect[2], rect[3]],
+ [rect[0], rect[3]],
+ ];
+ };
+ return RectGeometry;
+}(Component_1.VertexGeometry));
+exports.RectGeometry = RectGeometry;
+exports.default = RectGeometry;
+
+},{"../../../Component":275}],356:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var earcut_1 = require("earcut");
+var martinez = require("martinez-polygon-clipping");
+var polylabel = require("@mapbox/polylabel");
+var THREE = require("three");
+var Component_1 = require("../../../Component");
+/**
+ * @class VertexGeometry
+ * @abstract
+ * @classdesc Represents a vertex geometry.
+ */
+var VertexGeometry = /** @class */ (function (_super) {
+ __extends(VertexGeometry, _super);
+ /**
+ * Create a vertex geometry.
+ *
+ * @constructor
+ * @ignore
+ */
+ function VertexGeometry() {
+ var _this = _super.call(this) || this;
+ _this._subsampleThreshold = 0.005;
+ return _this;
+ }
+ /**
+ * Finds the polygon pole of inaccessibility, the most distant internal
+ * point from the polygon outline.
+ *
+ * @param {Array<Array<number>>} points2d - 2d points of outline to triangulate.
+ * @returns {Array<number>} Point of inaccessibility.
+ * @ignore
+ */
+ VertexGeometry.prototype._getPoleOfInaccessibility2d = function (points2d) {
+ var pole2d = polylabel([points2d], 3e-2);
+ return pole2d;
+ };
+ VertexGeometry.prototype._project = function (points2d, transform) {
+ var camera = this._createCamera(transform.upVector().toArray(), transform.unprojectSfM([0, 0], 0), transform.unprojectSfM([0, 0], 10));
+ return this._deunproject(points2d, transform, camera);
+ };
+ VertexGeometry.prototype._subsample = function (points2d, threshold) {
+ if (threshold === void 0) { threshold = this._subsampleThreshold; }
+ var subsampled = [];
+ var length = points2d.length;
+ for (var index = 0; index < length; index++) {
+ var p1 = points2d[index];
+ var p2 = points2d[(index + 1) % length];
+ subsampled.push(p1);
+ var dist = Math.sqrt(Math.pow((p2[0] - p1[0]), 2) + Math.pow((p2[1] - p1[1]), 2));
+ var subsamples = Math.floor(dist / threshold);
+ var coeff = 1 / (subsamples + 1);
+ for (var i = 1; i <= subsamples; i++) {
+ var alpha = i * coeff;
+ var subsample = [
+ (1 - alpha) * p1[0] + alpha * p2[0],
+ (1 - alpha) * p1[1] + alpha * p2[1],
+ ];
+ subsampled.push(subsample);
+ }
+ }
+ return subsampled;
+ };
+ /**
+ * Triangulates a 2d polygon and returns the triangle
+ * representation as a flattened array of 3d points.
+ *
+ * @param {Array<Array<number>>} points2d - 2d points of outline to triangulate.
+ * @param {Array<Array<number>>} points3d - 3d points of outline corresponding to the 2d points.
+ * @param {Array<Array<Array<number>>>} [holes2d] - 2d points of holes to triangulate.
+ * @param {Array<Array<Array<number>>>} [holes3d] - 3d points of holes corresponding to the 2d points.
+ * @returns {Array<number>} Flattened array of 3d points ordered based on the triangles.
+ * @ignore
+ */
+ VertexGeometry.prototype._triangulate = function (points2d, points3d, holes2d, holes3d) {
+ var data = [points2d.slice(0, -1)];
+ for (var _i = 0, _a = holes2d != null ? holes2d : []; _i < _a.length; _i++) {
+ var hole2d = _a[_i];
+ data.push(hole2d.slice(0, -1));
+ }
+ var points = points3d.slice(0, -1);
+ for (var _b = 0, _c = holes3d != null ? holes3d : []; _b < _c.length; _b++) {
+ var hole3d = _c[_b];
+ points = points.concat(hole3d.slice(0, -1));
+ }
+ var flattened = earcut_1.default.flatten(data);
+ var indices = earcut_1.default(flattened.vertices, flattened.holes, flattened.dimensions);
+ var triangles = [];
+ for (var i = 0; i < indices.length; ++i) {
+ var point = points[indices[i]];
+ triangles.push(point[0]);
+ triangles.push(point[1]);
+ triangles.push(point[2]);
+ }
+ return triangles;
+ };
+ VertexGeometry.prototype._triangulatePano = function (points2d, holes2d, transform) {
+ var triangles = [];
+ var epsilon = 1e-9;
+ var subareasX = 3;
+ var subareasY = 3;
+ for (var x = 0; x < subareasX; x++) {
+ for (var y = 0; y < subareasY; y++) {
+ var epsilonX0 = x === 0 ? -epsilon : epsilon;
+ var epsilonY0 = y === 0 ? -epsilon : epsilon;
+ var x0 = x / subareasX + epsilonX0;
+ var y0 = y / subareasY + epsilonY0;
+ var x1 = (x + 1) / subareasX + epsilon;
+ var y1 = (y + 1) / subareasY + epsilon;
+ var bbox2d = [
+ [x0, y0],
+ [x0, y1],
+ [x1, y1],
+ [x1, y0],
+ [x0, y0],
+ ];
+ var lookat2d = [
+ (2 * x + 1) / (2 * subareasX),
+ (2 * y + 1) / (2 * subareasY),
+ ];
+ triangles.push.apply(triangles, this._triangulateSubarea(points2d, holes2d, bbox2d, lookat2d, transform));
+ }
+ }
+ return triangles;
+ };
+ VertexGeometry.prototype._unproject = function (points2d, transform, distance) {
+ if (distance === void 0) { distance = 200; }
+ return points2d
+ .map(function (point) {
+ return transform.unprojectBasic(point, distance);
+ });
+ };
+ VertexGeometry.prototype._createCamera = function (upVector, position, lookAt) {
+ var camera = new THREE.Camera();
+ camera.up.copy(new THREE.Vector3().fromArray(upVector));
+ camera.position.copy(new THREE.Vector3().fromArray(position));
+ camera.lookAt(new THREE.Vector3().fromArray(lookAt));
+ camera.updateMatrix();
+ camera.updateMatrixWorld(true);
+ return camera;
+ };
+ VertexGeometry.prototype._deunproject = function (points2d, transform, camera) {
+ return points2d
+ .map(function (point2d) {
+ var pointWorld = transform.unprojectBasic(point2d, 10000);
+ var pointCamera = new THREE.Vector3(pointWorld[0], pointWorld[1], pointWorld[2])
+ .applyMatrix4(camera.matrixWorldInverse);
+ return [pointCamera.x / pointCamera.z, pointCamera.y / pointCamera.z];
+ });
+ };
+ VertexGeometry.prototype._triangulateSubarea = function (points2d, holes2d, bbox2d, lookat2d, transform) {
+ var intersections = martinez.intersection([points2d].concat(holes2d), [bbox2d]);
+ if (!intersections) {
+ return [];
+ }
+ var triangles = [];
+ var threshold = this._subsampleThreshold;
+ var camera = this._createCamera(transform.upVector().toArray(), transform.unprojectSfM([0, 0], 0), transform.unprojectBasic(lookat2d, 10));
+ for (var _i = 0, intersections_1 = intersections; _i < intersections_1.length; _i++) {
+ var intersection = intersections_1[_i];
+ var subsampledPolygon2d = this._subsample(intersection[0], threshold);
+ var polygon2d = this._deunproject(subsampledPolygon2d, transform, camera);
+ var polygon3d = this._unproject(subsampledPolygon2d, transform);
+ var polygonHoles2d = [];
+ var polygonHoles3d = [];
+ for (var i = 1; i < intersection.length; i++) {
+ var subsampledHole2d = this._subsample(intersection[i], threshold);
+ var hole2d = this._deunproject(subsampledHole2d, transform, camera);
+ var hole3d = this._unproject(subsampledHole2d, transform);
+ polygonHoles2d.push(hole2d);
+ polygonHoles3d.push(hole3d);
+ }
+ triangles.push.apply(triangles, this._triangulate(polygon2d, polygon3d, polygonHoles2d, polygonHoles3d));
+ }
+ return triangles;
+ };
+ return VertexGeometry;
+}(Component_1.Geometry));
+exports.VertexGeometry = VertexGeometry;
+exports.default = VertexGeometry;
+
+},{"../../../Component":275,"@mapbox/polylabel":1,"earcut":8,"martinez-polygon-clipping":22,"three":226}],357:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var rxjs_1 = require("rxjs");
+var Component_1 = require("../../../Component");
+var CreateHandlerBase = /** @class */ (function (_super) {
+ __extends(CreateHandlerBase, _super);
+ function CreateHandlerBase(component, container, navigator, viewportCoords, tagCreator) {
+ var _this = _super.call(this, component, container, navigator, viewportCoords) || this;
+ _this._tagCreator = tagCreator;
+ _this._geometryCreated$ = new rxjs_1.Subject();
+ return _this;
+ }
+ Object.defineProperty(CreateHandlerBase.prototype, "geometryCreated$", {
+ get: function () {
+ return this._geometryCreated$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ CreateHandlerBase.prototype._enable = function () {
+ this._enableCreate();
+ this._container.element.classList.add("component-tag-create");
+ };
+ CreateHandlerBase.prototype._disable = function () {
+ this._container.element.classList.remove("component-tag-create");
+ this._disableCreate();
+ };
+ CreateHandlerBase.prototype._validateBasic = function (basic) {
+ var x = basic[0];
+ var y = basic[1];
+ return 0 <= x && x <= 1 && 0 <= y && y <= 1;
+ };
+ CreateHandlerBase.prototype._mouseEventToBasic$ = function (mouseEvent$) {
+ var _this = this;
+ return mouseEvent$.pipe(operators_1.withLatestFrom(this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$), operators_1.map(function (_a) {
+ var event = _a[0], camera = _a[1], transform = _a[2];
+ return _this._mouseEventToBasic(event, _this._container.element, camera, transform);
+ }));
+ };
+ return CreateHandlerBase;
+}(Component_1.TagHandlerBase));
+exports.CreateHandlerBase = CreateHandlerBase;
+exports.default = CreateHandlerBase;
+
+},{"../../../Component":275,"rxjs":27,"rxjs/operators":225}],358:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../../Component");
+var CreatePointHandler = /** @class */ (function (_super) {
+ __extends(CreatePointHandler, _super);
+ function CreatePointHandler() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ CreatePointHandler.prototype._enableCreate = function () {
+ this._container.mouseService.deferPixels(this._name, 4);
+ this._geometryCreatedSubscription = this._mouseEventToBasic$(this._container.mouseService.proximateClick$).pipe(operators_1.filter(this._validateBasic), operators_1.map(function (basic) {
+ return new Component_1.PointGeometry(basic);
+ }))
+ .subscribe(this._geometryCreated$);
+ };
+ CreatePointHandler.prototype._disableCreate = function () {
+ this._container.mouseService.undeferPixels(this._name);
+ this._geometryCreatedSubscription.unsubscribe();
+ };
+ CreatePointHandler.prototype._getNameExtension = function () {
+ return "create-point";
+ };
+ return CreatePointHandler;
+}(Component_1.CreateHandlerBase));
+exports.CreatePointHandler = CreatePointHandler;
+exports.default = CreatePointHandler;
+
+},{"../../../Component":275,"rxjs/operators":225}],359:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../../Component");
+var CreatePolygonHandler = /** @class */ (function (_super) {
+ __extends(CreatePolygonHandler, _super);
+ function CreatePolygonHandler() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ CreatePolygonHandler.prototype._addPoint = function (tag, basicPoint) {
+ tag.addPoint(basicPoint);
+ };
+ Object.defineProperty(CreatePolygonHandler.prototype, "_create$", {
+ get: function () {
+ return this._tagCreator.createPolygon$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ CreatePolygonHandler.prototype._getNameExtension = function () {
+ return "create-polygon";
+ };
+ CreatePolygonHandler.prototype._setVertex2d = function (tag, basicPoint, transform) {
+ tag.geometry.setVertex2d(tag.geometry.polygon.length - 2, basicPoint, transform);
+ };
+ return CreatePolygonHandler;
+}(Component_1.CreateVertexHandler));
+exports.CreatePolygonHandler = CreatePolygonHandler;
+exports.default = CreatePolygonHandler;
+
+},{"../../../Component":275}],360:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../../Component");
+var CreateRectDragHandler = /** @class */ (function (_super) {
+ __extends(CreateRectDragHandler, _super);
+ function CreateRectDragHandler() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ CreateRectDragHandler.prototype._enableCreate = function () {
+ var _this = this;
+ this._container.mouseService.claimMouse(this._name, 2);
+ this._deleteSubscription = this._navigator.stateService.currentTransform$.pipe(operators_1.map(function (transform) { return null; }), operators_1.skip(1))
+ .subscribe(this._tagCreator.delete$);
+ this._createSubscription = this._mouseEventToBasic$(this._container.mouseService.filtered$(this._name, this._container.mouseService.mouseDragStart$)).pipe(operators_1.filter(this._validateBasic))
+ .subscribe(this._tagCreator.createRect$);
+ this._initializeAnchorIndexingSubscription = this._tagCreator.tag$.pipe(operators_1.filter(function (tag) {
+ return !!tag;
+ }))
+ .subscribe(function (tag) {
+ tag.geometry.initializeAnchorIndexing();
+ });
+ var basicMouse$ = rxjs_1.combineLatest(rxjs_1.merge(this._container.mouseService.filtered$(this._name, this._container.mouseService.mouseMove$), this._container.mouseService.filtered$(this._name, this._container.mouseService.domMouseMove$)), this._container.renderService.renderCamera$).pipe(operators_1.withLatestFrom(this._navigator.stateService.currentTransform$), operators_1.map(function (_a) {
+ var _b = _a[0], event = _b[0], camera = _b[1], transform = _a[1];
+ return _this._mouseEventToBasic(event, _this._container.element, camera, transform);
+ }));
+ this._setVertexSubscription = this._tagCreator.tag$.pipe(operators_1.switchMap(function (tag) {
+ return !!tag ?
+ rxjs_1.combineLatest(rxjs_1.of(tag), basicMouse$, _this._navigator.stateService.currentTransform$) :
+ rxjs_1.empty();
+ }))
+ .subscribe(function (_a) {
+ var tag = _a[0], basicPoint = _a[1], transform = _a[2];
+ tag.geometry.setOppositeVertex2d(basicPoint, transform);
+ });
+ var basicMouseDragEnd$ = this._container.mouseService.mouseDragEnd$.pipe(operators_1.withLatestFrom(this._mouseEventToBasic$(this._container.mouseService.filtered$(this._name, this._container.mouseService.mouseDrag$)).pipe(operators_1.filter(this._validateBasic)), function (event, basicPoint) {
+ return basicPoint;
+ }), operators_1.share());
+ this._addPointSubscription = this._tagCreator.tag$.pipe(operators_1.switchMap(function (tag) {
+ return !!tag ?
+ rxjs_1.combineLatest(rxjs_1.of(tag), basicMouseDragEnd$) :
+ rxjs_1.empty();
+ }))
+ .subscribe(function (_a) {
+ var tag = _a[0], basicPoint = _a[1];
+ var rectGeometry = tag.geometry;
+ if (!rectGeometry.validate(basicPoint)) {
+ basicPoint = rectGeometry.getNonAdjustedVertex2d(3);
+ }
+ tag.addPoint(basicPoint);
+ });
+ this._geometryCreatedSubscription = this._tagCreator.tag$.pipe(operators_1.switchMap(function (tag) {
+ return !!tag ?
+ tag.created$.pipe(operators_1.map(function (t) {
+ return t.geometry;
+ })) :
+ rxjs_1.empty();
+ }))
+ .subscribe(this._geometryCreated$);
+ };
+ CreateRectDragHandler.prototype._disableCreate = function () {
+ this._container.mouseService.unclaimMouse(this._name);
+ this._tagCreator.delete$.next(null);
+ this._addPointSubscription.unsubscribe();
+ this._createSubscription.unsubscribe();
+ this._deleteSubscription.unsubscribe();
+ this._geometryCreatedSubscription.unsubscribe();
+ this._initializeAnchorIndexingSubscription.unsubscribe();
+ this._setVertexSubscription.unsubscribe();
+ };
+ CreateRectDragHandler.prototype._getNameExtension = function () {
+ return "create-rect-drag";
+ };
+ return CreateRectDragHandler;
+}(Component_1.CreateHandlerBase));
+exports.CreateRectDragHandler = CreateRectDragHandler;
+exports.default = CreateRectDragHandler;
+
+},{"../../../Component":275,"rxjs":27,"rxjs/operators":225}],361:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../../Component");
+var CreateRectHandler = /** @class */ (function (_super) {
+ __extends(CreateRectHandler, _super);
+ function CreateRectHandler() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ Object.defineProperty(CreateRectHandler.prototype, "_create$", {
+ get: function () {
+ return this._tagCreator.createRect$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ CreateRectHandler.prototype._addPoint = function (tag, basicPoint) {
+ var rectGeometry = tag.geometry;
+ if (!rectGeometry.validate(basicPoint)) {
+ basicPoint = rectGeometry.getNonAdjustedVertex2d(3);
+ }
+ tag.addPoint(basicPoint);
+ };
+ CreateRectHandler.prototype._enable = function () {
+ _super.prototype._enable.call(this);
+ this._initializeAnchorIndexingSubscription = this._tagCreator.tag$.pipe(operators_1.filter(function (tag) {
+ return !!tag;
+ }))
+ .subscribe(function (tag) {
+ tag.geometry.initializeAnchorIndexing();
+ });
+ };
+ CreateRectHandler.prototype._disable = function () {
+ _super.prototype._disable.call(this);
+ this._initializeAnchorIndexingSubscription.unsubscribe();
+ };
+ CreateRectHandler.prototype._getNameExtension = function () {
+ return "create-rect";
+ };
+ CreateRectHandler.prototype._setVertex2d = function (tag, basicPoint, transform) {
+ tag.geometry.setOppositeVertex2d(basicPoint, transform);
+ };
+ return CreateRectHandler;
+}(Component_1.CreateVertexHandler));
+exports.CreateRectHandler = CreateRectHandler;
+exports.default = CreateRectHandler;
+
+},{"../../../Component":275,"rxjs/operators":225}],362:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../../Component");
+var CreateVertexHandler = /** @class */ (function (_super) {
+ __extends(CreateVertexHandler, _super);
+ function CreateVertexHandler() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ CreateVertexHandler.prototype._enableCreate = function () {
+ var _this = this;
+ this._container.mouseService.deferPixels(this._name, 4);
+ var transformChanged$ = this._navigator.stateService.currentTransform$.pipe(operators_1.map(function (transform) { }), operators_1.publishReplay(1), operators_1.refCount());
+ this._deleteSubscription = transformChanged$.pipe(operators_1.skip(1))
+ .subscribe(this._tagCreator.delete$);
+ var basicClick$ = this._mouseEventToBasic$(this._container.mouseService.proximateClick$).pipe(operators_1.share());
+ this._createSubscription = transformChanged$.pipe(operators_1.switchMap(function () {
+ return basicClick$.pipe(operators_1.filter(_this._validateBasic), operators_1.take(1));
+ }))
+ .subscribe(this._create$);
+ this._setVertexSubscription = this._tagCreator.tag$.pipe(operators_1.switchMap(function (tag) {
+ return !!tag ?
+ rxjs_1.combineLatest(rxjs_1.of(tag), rxjs_1.merge(_this._container.mouseService.mouseMove$, _this._container.mouseService.domMouseMove$), _this._container.renderService.renderCamera$, _this._navigator.stateService.currentTransform$) :
+ rxjs_1.empty();
+ }))
+ .subscribe(function (_a) {
+ var tag = _a[0], event = _a[1], camera = _a[2], transform = _a[3];
+ var basicPoint = _this._mouseEventToBasic(event, _this._container.element, camera, transform);
+ _this._setVertex2d(tag, basicPoint, transform);
+ });
+ this._addPointSubscription = this._tagCreator.tag$.pipe(operators_1.switchMap(function (tag) {
+ return !!tag ?
+ rxjs_1.combineLatest(rxjs_1.of(tag), basicClick$) :
+ rxjs_1.empty();
+ }))
+ .subscribe(function (_a) {
+ var tag = _a[0], basicPoint = _a[1];
+ _this._addPoint(tag, basicPoint);
+ });
+ this._geometryCreateSubscription = this._tagCreator.tag$.pipe(operators_1.switchMap(function (tag) {
+ return !!tag ?
+ tag.created$.pipe(operators_1.map(function (t) {
+ return t.geometry;
+ })) :
+ rxjs_1.empty();
+ }))
+ .subscribe(this._geometryCreated$);
+ };
+ CreateVertexHandler.prototype._disableCreate = function () {
+ this._container.mouseService.undeferPixels(this._name);
+ this._tagCreator.delete$.next(null);
+ this._addPointSubscription.unsubscribe();
+ this._createSubscription.unsubscribe();
+ this._deleteSubscription.unsubscribe();
+ this._geometryCreateSubscription.unsubscribe();
+ this._setVertexSubscription.unsubscribe();
+ };
+ return CreateVertexHandler;
+}(Component_1.CreateHandlerBase));
+exports.CreateVertexHandler = CreateVertexHandler;
+exports.default = CreateVertexHandler;
+
+},{"../../../Component":275,"rxjs":27,"rxjs/operators":225}],363:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Component_1 = require("../../../Component");
+var EditVertexHandler = /** @class */ (function (_super) {
+ __extends(EditVertexHandler, _super);
+ function EditVertexHandler(component, container, navigator, viewportCoords, tagSet) {
+ var _this = _super.call(this, component, container, navigator, viewportCoords) || this;
+ _this._tagSet = tagSet;
+ return _this;
+ }
+ EditVertexHandler.prototype._enable = function () {
+ var _this = this;
+ var interaction$ = this._tagSet.changed$.pipe(operators_1.map(function (tagSet) {
+ return tagSet.getAll();
+ }), operators_1.switchMap(function (tags) {
+ return rxjs_1.from(tags).pipe(operators_1.mergeMap(function (tag) {
+ return tag.interact$;
+ }));
+ }), operators_1.switchMap(function (interaction) {
+ return rxjs_1.concat(rxjs_1.of(interaction), _this._container.mouseService.documentMouseUp$.pipe(operators_1.map(function () {
+ return { offsetX: 0, offsetY: 0, operation: Component_1.TagOperation.None, tag: null };
+ }), operators_1.first()));
+ }), operators_1.share());
+ var mouseMove$ = rxjs_1.merge(this._container.mouseService.mouseMove$, this._container.mouseService.domMouseMove$).pipe(operators_1.share());
+ this._claimMouseSubscription = interaction$.pipe(operators_1.switchMap(function (interaction) {
+ return !!interaction.tag ? _this._container.mouseService.domMouseDragStart$ : rxjs_1.empty();
+ }))
+ .subscribe(function () {
+ _this._container.mouseService.claimMouse(_this._name, 3);
+ });
+ this._cursorSubscription = interaction$.pipe(operators_1.map(function (interaction) {
+ return interaction.cursor;
+ }), operators_1.distinctUntilChanged())
+ .subscribe(function (cursor) {
+ var interactionCursors = ["crosshair", "move", "nesw-resize", "nwse-resize"];
+ for (var _i = 0, interactionCursors_1 = interactionCursors; _i < interactionCursors_1.length; _i++) {
+ var interactionCursor = interactionCursors_1[_i];
+ _this._container.element.classList.remove("component-tag-edit-" + interactionCursor);
+ }
+ if (!!cursor) {
+ _this._container.element.classList.add("component-tag-edit-" + cursor);
+ }
+ });
+ this._unclaimMouseSubscription = this._container.mouseService
+ .filtered$(this._name, this._container.mouseService.domMouseDragEnd$)
+ .subscribe(function (e) {
+ _this._container.mouseService.unclaimMouse(_this._name);
+ });
+ this._preventDefaultSubscription = interaction$.pipe(operators_1.switchMap(function (interaction) {
+ return !!interaction.tag ?
+ _this._container.mouseService.documentMouseMove$ :
+ rxjs_1.empty();
+ }))
+ .subscribe(function (event) {
+ event.preventDefault(); // prevent selection of content outside the viewer
+ });
+ this._updateGeometrySubscription = interaction$.pipe(operators_1.switchMap(function (interaction) {
+ if (interaction.operation === Component_1.TagOperation.None || !interaction.tag) {
+ return rxjs_1.empty();
+ }
+ var mouseDrag$ = _this._container.mouseService
+ .filtered$(_this._name, _this._container.mouseService.domMouseDrag$).pipe(operators_1.filter(function (event) {
+ return _this._viewportCoords.insideElement(event, _this._container.element);
+ }));
+ return rxjs_1.combineLatest(mouseDrag$, _this._container.renderService.renderCamera$).pipe(operators_1.withLatestFrom(rxjs_1.of(interaction), _this._navigator.stateService.currentTransform$, function (_a, i, transform) {
+ var event = _a[0], render = _a[1];
+ return [event, render, i, transform];
+ }));
+ }))
+ .subscribe(function (_a) {
+ var mouseEvent = _a[0], renderCamera = _a[1], interaction = _a[2], transform = _a[3];
+ var basic = _this._mouseEventToBasic(mouseEvent, _this._container.element, renderCamera, transform, interaction.offsetX, interaction.offsetY);
+ var geometry = interaction.tag.geometry;
+ if (interaction.operation === Component_1.TagOperation.Centroid) {
+ geometry.setCentroid2d(basic, transform);
+ }
+ else if (interaction.operation === Component_1.TagOperation.Vertex) {
+ geometry.setVertex2d(interaction.vertexIndex, basic, transform);
+ }
+ });
+ };
+ EditVertexHandler.prototype._disable = function () {
+ this._claimMouseSubscription.unsubscribe();
+ this._cursorSubscription.unsubscribe();
+ this._preventDefaultSubscription.unsubscribe();
+ this._unclaimMouseSubscription.unsubscribe();
+ this._updateGeometrySubscription.unsubscribe();
+ };
+ EditVertexHandler.prototype._getNameExtension = function () {
+ return "edit-vertex";
+ };
+ return EditVertexHandler;
+}(Component_1.TagHandlerBase));
+exports.EditVertexHandler = EditVertexHandler;
+exports.default = EditVertexHandler;
+
+
+},{"../../../Component":275,"rxjs":27,"rxjs/operators":225}],364:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../../Component");
+var TagHandlerBase = /** @class */ (function (_super) {
+ __extends(TagHandlerBase, _super);
+ function TagHandlerBase(component, container, navigator, viewportCoords) {
+ var _this = _super.call(this, component, container, navigator) || this;
+ _this._name = _this._component.name + "-" + _this._getNameExtension();
+ _this._viewportCoords = viewportCoords;
+ return _this;
+ }
+ TagHandlerBase.prototype._getConfiguration = function (enable) {
+ return {};
+ };
+ TagHandlerBase.prototype._mouseEventToBasic = function (event, element, camera, transform, offsetX, offsetY) {
+ offsetX = offsetX != null ? offsetX : 0;
+ offsetY = offsetY != null ? offsetY : 0;
+ var _a = this._viewportCoords.canvasPosition(event, element), canvasX = _a[0], canvasY = _a[1];
+ var basic = this._viewportCoords.canvasToBasic(canvasX - offsetX, canvasY - offsetY, element, transform, camera.perspective);
+ return basic;
+ };
+ return TagHandlerBase;
+}(Component_1.HandlerBase));
+exports.TagHandlerBase = TagHandlerBase;
+exports.default = TagHandlerBase;
+
+
+},{"../../../Component":275}],365:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var operators_1 = require("rxjs/operators");
+var THREE = require("three");
+var vd = require("virtual-dom");
+var rxjs_1 = require("rxjs");
+var Component_1 = require("../../../Component");
+var Geo_1 = require("../../../Geo");
+var OutlineCreateTag = /** @class */ (function () {
+ function OutlineCreateTag(geometry, options, transform, viewportCoords) {
+ var _this = this;
+ this._geometry = geometry;
+ this._options = { color: options.color == null ? 0xFFFFFF : options.color };
+ this._transform = transform;
+ this._viewportCoords = !!viewportCoords ? viewportCoords : new Geo_1.ViewportCoords();
+ this._outline = this._createOutine();
+ this._glObjects = [this._outline];
+ this._aborted$ = new rxjs_1.Subject();
+ this._created$ = new rxjs_1.Subject();
+ this._glObjectsChanged$ = new rxjs_1.Subject();
+ this._geometryChangedSubscription = this._geometry.changed$
+ .subscribe(function (vertexGeometry) {
+ _this._disposeOutline();
+ _this._outline = _this._createOutine();
+ _this._glObjects = [_this._outline];
+ _this._glObjectsChanged$.next(_this);
+ });
+ }
+ Object.defineProperty(OutlineCreateTag.prototype, "geometry", {
+ get: function () {
+ return this._geometry;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineCreateTag.prototype, "glObjects", {
+ get: function () {
+ return this._glObjects;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineCreateTag.prototype, "aborted$", {
+ get: function () {
+ return this._aborted$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineCreateTag.prototype, "created$", {
+ get: function () {
+ return this._created$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineCreateTag.prototype, "glObjectsChanged$", {
+ get: function () {
+ return this._glObjectsChanged$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineCreateTag.prototype, "geometryChanged$", {
+ get: function () {
+ var _this = this;
+ return this._geometry.changed$.pipe(operators_1.map(function (geometry) {
+ return _this;
+ }));
+ },
+ enumerable: true,
+ configurable: true
+ });
+ OutlineCreateTag.prototype.dispose = function () {
+ this._disposeOutline();
+ this._geometryChangedSubscription.unsubscribe();
+ };
+ OutlineCreateTag.prototype.getDOMObjects = function (camera, size) {
+ var _this = this;
+ var vNodes = [];
+ var container = {
+ offsetHeight: size.height, offsetWidth: size.width,
+ };
+ var abort = function (e) {
+ e.stopPropagation();
+ _this._aborted$.next(_this);
+ };
+ if (this._geometry instanceof Component_1.RectGeometry) {
+ var anchorIndex = this._geometry.anchorIndex;
+ var vertexIndex = anchorIndex === undefined ? 1 : anchorIndex;
+ var _a = this._geometry.getVertex2d(vertexIndex), basicX = _a[0], basicY = _a[1];
+ var canvasPoint = this._viewportCoords.basicToCanvasSafe(basicX, basicY, container, this._transform, camera);
+ if (canvasPoint != null) {
+ var background = this._colorToBackground(this._options.color);
+ var transform = this._canvasToTransform(canvasPoint);
+ var pointProperties = {
+ style: { background: background, transform: transform },
+ };
+ var completerProperties = {
+ onclick: abort,
+ style: { transform: transform },
+ };
+ vNodes.push(vd.h("div.TagInteractor", completerProperties, []));
+ vNodes.push(vd.h("div.TagVertex", pointProperties, []));
+ }
+ }
+ else if (this._geometry instanceof Component_1.PolygonGeometry) {
+ var polygonGeometry_1 = this._geometry;
+ var _b = polygonGeometry_1.getVertex2d(0), firstVertexBasicX = _b[0], firstVertexBasicY = _b[1];
+ var firstVertexCanvas = this._viewportCoords.basicToCanvasSafe(firstVertexBasicX, firstVertexBasicY, container, this._transform, camera);
+ if (firstVertexCanvas != null) {
+ var firstOnclick = polygonGeometry_1.polygon.length > 4 ?
+ function (e) {
+ e.stopPropagation();
+ polygonGeometry_1.removeVertex2d(polygonGeometry_1.polygon.length - 2);
+ _this._created$.next(_this);
+ } :
+ abort;
+ var transform = this._canvasToTransform(firstVertexCanvas);
+ var completerProperties = {
+ onclick: firstOnclick,
+ style: { transform: transform },
+ };
+ var firstClass = polygonGeometry_1.polygon.length > 4 ?
+ "TagCompleter" :
+ "TagInteractor";
+ vNodes.push(vd.h("div." + firstClass, completerProperties, []));
+ }
+ if (polygonGeometry_1.polygon.length > 3) {
+ var _c = polygonGeometry_1.getVertex2d(polygonGeometry_1.polygon.length - 3), lastVertexBasicX = _c[0], lastVertexBasicY = _c[1];
+ var lastVertexCanvas = this._viewportCoords.basicToCanvasSafe(lastVertexBasicX, lastVertexBasicY, container, this._transform, camera);
+ if (lastVertexCanvas != null) {
+ var remove = function (e) {
+ e.stopPropagation();
+ polygonGeometry_1.removeVertex2d(polygonGeometry_1.polygon.length - 3);
+ };
+ var transform = this._canvasToTransform(lastVertexCanvas);
+ var completerProperties = {
+ onclick: remove,
+ style: { transform: transform },
+ };
+ vNodes.push(vd.h("div.TagInteractor", completerProperties, []));
+ }
+ }
+ var verticesBasic = polygonGeometry_1.polygon.slice();
+ verticesBasic.splice(-2, 2);
+ for (var _i = 0, verticesBasic_1 = verticesBasic; _i < verticesBasic_1.length; _i++) {
+ var vertexBasic = verticesBasic_1[_i];
+ var vertexCanvas = this._viewportCoords.basicToCanvasSafe(vertexBasic[0], vertexBasic[1], container, this._transform, camera);
+ if (vertexCanvas != null) {
+ var background = this._colorToBackground(this._options.color);
+ var transform = this._canvasToTransform(vertexCanvas);
+ var pointProperties = {
+ style: {
+ background: background,
+ transform: transform,
+ },
+ };
+ vNodes.push(vd.h("div.TagVertex", pointProperties, []));
+ }
+ }
+ }
+ return vNodes;
+ };
+ OutlineCreateTag.prototype.addPoint = function (point) {
+ if (this._geometry instanceof Component_1.RectGeometry) {
+ var rectGeometry = this._geometry;
+ if (!rectGeometry.validate(point)) {
+ return;
+ }
+ this._created$.next(this);
+ }
+ else if (this._geometry instanceof Component_1.PolygonGeometry) {
+ var polygonGeometry = this._geometry;
+ polygonGeometry.addVertex2d(point);
+ }
+ };
+ OutlineCreateTag.prototype._canvasToTransform = function (canvas) {
+ var canvasX = Math.round(canvas[0]);
+ var canvasY = Math.round(canvas[1]);
+ var transform = "translate(-50%,-50%) translate(" + canvasX + "px," + canvasY + "px)";
+ return transform;
+ };
+ OutlineCreateTag.prototype._colorToBackground = function (color) {
+ return "#" + ("000000" + color.toString(16)).substr(-6);
+ };
+ OutlineCreateTag.prototype._createOutine = function () {
+ var polygon3d = this._geometry instanceof Component_1.RectGeometry ?
+ this._geometry.getPoints3d(this._transform) :
+ this._geometry.getVertices3d(this._transform);
+ var positions = this._getLinePositions(polygon3d);
+ var geometry = new THREE.BufferGeometry();
+ geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+ var material = new THREE.LineBasicMaterial({
+ color: this._options.color,
+ linewidth: 1,
+ });
+ return new THREE.Line(geometry, material);
+ };
+ OutlineCreateTag.prototype._disposeOutline = function () {
+ if (this._outline == null) {
+ return;
+ }
+ var line = this._outline;
+ line.geometry.dispose();
+ line.material.dispose();
+ this._outline = null;
+ this._glObjects = [];
+ };
+ OutlineCreateTag.prototype._getLinePositions = function (polygon3d) {
+ var length = polygon3d.length;
+ var positions = new Float32Array(length * 3);
+ for (var i = 0; i < length; ++i) {
+ var index = 3 * i;
+ var position = polygon3d[i];
+ positions[index] = position[0];
+ positions[index + 1] = position[1];
+ positions[index + 2] = position[2];
+ }
+ return positions;
+ };
+ return OutlineCreateTag;
+}());
+exports.OutlineCreateTag = OutlineCreateTag;
+exports.default = OutlineCreateTag;
+
+
+},{"../../../Component":275,"../../../Geo":278,"rxjs":27,"rxjs/operators":225,"three":226,"virtual-dom":231}],366:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var vd = require("virtual-dom");
+var Component_1 = require("../../../Component");
+/**
+ * @class OutlineRenderTag
+ * @classdesc Tag visualizing the properties of an OutlineTag.
+ */
+var OutlineRenderTag = /** @class */ (function (_super) {
+ __extends(OutlineRenderTag, _super);
+ function OutlineRenderTag(tag, transform) {
+ var _this = _super.call(this, tag, transform) || this;
+ _this._fill = !transform.gpano ?
+ _this._createFill() :
+ transform.fullPano &&
+ tag.domain === Component_1.TagDomain.TwoDimensional &&
+ tag.geometry instanceof Component_1.PolygonGeometry ?
+ _this._createFill() :
+ null;
+ _this._holes = _this._tag.lineWidth >= 1 ?
+ _this._createHoles() :
+ [];
+ _this._outline = _this._tag.lineWidth >= 1 ?
+ _this._createOutline() :
+ null;
+ _this._geometryChangedSubscription = _this._tag.geometry.changed$
+ .subscribe(function () {
+ if (_this._fill != null) {
+ _this._updateFillGeometry();
+ }
+ if (_this._holes.length > 0) {
+ _this._updateHoleGeometries();
+ }
+ if (_this._outline != null) {
+ _this._updateOulineGeometry();
+ }
+ });
+ _this._changedSubscription = _this._tag.changed$
+ .subscribe(function () {
+ var glObjectsChanged = false;
+ if (_this._fill != null) {
+ _this._updateFillMaterial(_this._fill.material);
+ }
+ if (_this._outline == null) {
+ if (_this._tag.lineWidth >= 1) {
+ _this._holes = _this._createHoles();
+ _this._outline = _this._createOutline();
+ glObjectsChanged = true;
+ }
+ }
+ else {
+ _this._updateHoleMaterials();
+ _this._updateOutlineMaterial();
+ }
+ if (glObjectsChanged) {
+ _this._glObjectsChanged$.next(_this);
+ }
+ });
+ return _this;
+ }
+ OutlineRenderTag.prototype.dispose = function () {
+ this._disposeFill();
+ this._disposeHoles();
+ this._disposeOutline();
+ this._changedSubscription.unsubscribe();
+ this._geometryChangedSubscription.unsubscribe();
+ };
+ OutlineRenderTag.prototype.getDOMObjects = function (atlas, camera, size) {
+ var _this = this;
+ var vNodes = [];
+ var isRect = this._tag.geometry instanceof Component_1.RectGeometry;
+ var isPerspective = !this._transform.gpano;
+ var container = {
+ offsetHeight: size.height, offsetWidth: size.width,
+ };
+ if (this._tag.icon != null && (isRect || isPerspective)) {
+ var _a = this._tag.geometry instanceof Component_1.RectGeometry ?
+ this._tag.geometry.getVertex2d(this._tag.iconIndex) :
+ this._tag.geometry.getPoleOfInaccessibility2d(), iconBasicX = _a[0], iconBasicY = _a[1];
+ var iconCanvas = this._viewportCoords.basicToCanvasSafe(iconBasicX, iconBasicY, container, this._transform, camera);
+ if (iconCanvas != null) {
+ var interact = function (e) {
+ _this._interact$.next({ offsetX: 0, offsetY: 0, operation: Component_1.TagOperation.None, tag: _this._tag });
+ };
+ if (atlas.loaded) {
+ var sprite = atlas.getDOMSprite(this._tag.icon, this._tag.iconFloat);
+ var iconCanvasX = Math.round(iconCanvas[0]);
+ var iconCanvasY = Math.round(iconCanvas[1]);
+ var transform = "translate(" + iconCanvasX + "px," + iconCanvasY + "px)";
+ var click = function (e) {
+ e.stopPropagation();
+ _this._tag.click$.next(_this._tag);
+ };
+ var properties = {
+ onclick: click,
+ onmousedown: interact,
+ style: { transform: transform },
+ };
+ vNodes.push(vd.h("div.TagSymbol", properties, [sprite]));
+ }
+ }
+ }
+ else if (this._tag.text != null && (isRect || isPerspective)) {
+ var _b = this._tag.geometry instanceof Component_1.RectGeometry ?
+ this._tag.geometry.getVertex2d(3) :
+ this._tag.geometry.getPoleOfInaccessibility2d(), textBasicX = _b[0], textBasicY = _b[1];
+ var textCanvas = this._viewportCoords.basicToCanvasSafe(textBasicX, textBasicY, container, this._transform, camera);
+ if (textCanvas != null) {
+ var textCanvasX = Math.round(textCanvas[0]);
+ var textCanvasY = Math.round(textCanvas[1]);
+ var transform = this._tag.geometry instanceof Component_1.RectGeometry ?
+ "translate(" + textCanvasX + "px," + textCanvasY + "px)" :
+ "translate(-50%, -50%) translate(" + textCanvasX + "px," + textCanvasY + "px)";
+ var interact = function (e) {
+ _this._interact$.next({ offsetX: 0, offsetY: 0, operation: Component_1.TagOperation.None, tag: _this._tag });
+ };
+ var properties = {
+ onmousedown: interact,
+ style: {
+ color: this._colorToCss(this._tag.textColor),
+ transform: transform,
+ },
+ textContent: this._tag.text,
+ };
+ vNodes.push(vd.h("span.TagSymbol", properties, []));
+ }
+ }
+ if (!this._tag.editable) {
+ return vNodes;
+ }
+ var lineColor = this._colorToCss(this._tag.lineColor);
+ if (this._tag.geometry instanceof Component_1.RectGeometry) {
+ var _c = this._tag.geometry.getCentroid2d(), centroidBasicX = _c[0], centroidBasicY = _c[1];
+ var centroidCanvas = this._viewportCoords.basicToCanvasSafe(centroidBasicX, centroidBasicY, container, this._transform, camera);
+ if (centroidCanvas != null) {
+ var interact = this._interact(Component_1.TagOperation.Centroid, "move");
+ var centroidCanvasX = Math.round(centroidCanvas[0]);
+ var centroidCanvasY = Math.round(centroidCanvas[1]);
+ var transform = "translate(-50%, -50%) translate(" + centroidCanvasX + "px," + centroidCanvasY + "px)";
+ var properties = {
+ onmousedown: interact,
+ style: { background: lineColor, transform: transform },
+ };
+ vNodes.push(vd.h("div.TagMover", properties, []));
+ }
+ }
+ var vertices2d = this._tag.geometry.getVertices2d();
+ for (var i = 0; i < vertices2d.length - 1; i++) {
+ if (isRect &&
+ ((this._tag.icon != null && i === this._tag.iconIndex) ||
+ (this._tag.icon == null && this._tag.text != null && i === 3))) {
+ continue;
+ }
+ var _d = vertices2d[i], vertexBasicX = _d[0], vertexBasicY = _d[1];
+ var vertexCanvas = this._viewportCoords.basicToCanvasSafe(vertexBasicX, vertexBasicY, container, this._transform, camera);
+ if (vertexCanvas == null) {
+ continue;
+ }
+ var cursor = isRect ?
+ i % 2 === 0 ? "nesw-resize" : "nwse-resize" :
+ "crosshair";
+ var interact = this._interact(Component_1.TagOperation.Vertex, cursor, i);
+ var vertexCanvasX = Math.round(vertexCanvas[0]);
+ var vertexCanvasY = Math.round(vertexCanvas[1]);
+ var transform = "translate(-50%, -50%) translate(" + vertexCanvasX + "px," + vertexCanvasY + "px)";
+ var properties = {
+ onmousedown: interact,
+ style: { background: lineColor, transform: transform, cursor: cursor },
+ };
+ vNodes.push(vd.h("div.TagResizer", properties, []));
+ if (!this._tag.indicateVertices) {
+ continue;
+ }
+ var pointProperties = {
+ style: { background: lineColor, transform: transform },
+ };
+ vNodes.push(vd.h("div.TagVertex", pointProperties, []));
+ }
+ return vNodes;
+ };
+ OutlineRenderTag.prototype.getGLObjects = function () {
+ var glObjects = [];
+ if (this._fill != null) {
+ glObjects.push(this._fill);
+ }
+ for (var _i = 0, _a = this._holes; _i < _a.length; _i++) {
+ var hole = _a[_i];
+ glObjects.push(hole);
+ }
+ if (this._outline != null) {
+ glObjects.push(this._outline);
+ }
+ return glObjects;
+ };
+ OutlineRenderTag.prototype.getRetrievableObjects = function () {
+ return this._fill != null ? [this._fill] : [];
+ };
+ OutlineRenderTag.prototype._colorToCss = function (color) {
+ return "#" + ("000000" + color.toString(16)).substr(-6);
+ };
+ OutlineRenderTag.prototype._createFill = function () {
+ var triangles = this._getTriangles();
+ var positions = new Float32Array(triangles);
+ var geometry = new THREE.BufferGeometry();
+ geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+ geometry.computeBoundingSphere();
+ var material = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide, transparent: true });
+ this._updateFillMaterial(material);
+ return new THREE.Mesh(geometry, material);
+ };
+ OutlineRenderTag.prototype._createHoles = function () {
+ var holes = [];
+ if (this._tag.geometry instanceof Component_1.PolygonGeometry) {
+ var holes3d = this._getHoles3d();
+ for (var _i = 0, holes3d_1 = holes3d; _i < holes3d_1.length; _i++) {
+ var holePoints3d = holes3d_1[_i];
+ var hole = this._createLine(holePoints3d);
+ holes.push(hole);
+ }
+ }
+ return holes;
+ };
+ OutlineRenderTag.prototype._createLine = function (points3d) {
+ var positions = this._getLinePositions(points3d);
+ var geometry = new THREE.BufferGeometry();
+ geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+ geometry.computeBoundingSphere();
+ var material = new THREE.LineBasicMaterial();
+ this._updateLineBasicMaterial(material);
+ var line = new THREE.Line(geometry, material);
+ line.renderOrder = 1;
+ return line;
+ };
+ OutlineRenderTag.prototype._createOutline = function () {
+ return this._createLine(this._getPoints3d());
+ };
+ OutlineRenderTag.prototype._disposeFill = function () {
+ if (this._fill == null) {
+ return;
+ }
+ this._fill.geometry.dispose();
+ this._fill.material.dispose();
+ this._fill = null;
+ };
+ OutlineRenderTag.prototype._disposeHoles = function () {
+ for (var _i = 0, _a = this._holes; _i < _a.length; _i++) {
+ var hole = _a[_i];
+ hole.geometry.dispose();
+ hole.material.dispose();
+ }
+ this._holes = [];
+ };
+ OutlineRenderTag.prototype._disposeOutline = function () {
+ if (this._outline == null) {
+ return;
+ }
+ this._outline.geometry.dispose();
+ this._outline.material.dispose();
+ this._outline = null;
+ };
+ OutlineRenderTag.prototype._getLinePositions = function (points3d) {
+ var length = points3d.length;
+ var positions = new Float32Array(length * 3);
+ for (var i = 0; i < length; ++i) {
+ var index = 3 * i;
+ var position = points3d[i];
+ positions[index + 0] = position[0];
+ positions[index + 1] = position[1];
+ positions[index + 2] = position[2];
+ }
+ return positions;
+ };
+ OutlineRenderTag.prototype._getHoles3d = function () {
+ var polygonGeometry = this._tag.geometry;
+ return this._in3dDomain() ?
+ polygonGeometry.getHoleVertices3d(this._transform) :
+ polygonGeometry.getHolePoints3d(this._transform);
+ };
+ OutlineRenderTag.prototype._getPoints3d = function () {
+ return this._in3dDomain() ?
+ this._tag.geometry.getVertices3d(this._transform) :
+ this._tag.geometry.getPoints3d(this._transform);
+ };
+ OutlineRenderTag.prototype._getTriangles = function () {
+ return this._in3dDomain() ?
+ this._tag.geometry.get3dDomainTriangles3d(this._transform) :
+ this._tag.geometry.getTriangles3d(this._transform);
+ };
+ OutlineRenderTag.prototype._in3dDomain = function () {
+ return this._tag.geometry instanceof Component_1.PolygonGeometry && this._tag.domain === Component_1.TagDomain.ThreeDimensional;
+ };
+ OutlineRenderTag.prototype._interact = function (operation, cursor, vertexIndex) {
+ var _this = this;
+ return function (e) {
+ var offsetX = e.offsetX - e.target.offsetWidth / 2;
+ var offsetY = e.offsetY - e.target.offsetHeight / 2;
+ _this._interact$.next({
+ cursor: cursor,
+ offsetX: offsetX,
+ offsetY: offsetY,
+ operation: operation,
+ tag: _this._tag,
+ vertexIndex: vertexIndex,
+ });
+ };
+ };
+ OutlineRenderTag.prototype._updateFillGeometry = function () {
+ var triangles = this._getTriangles();
+ var positions = new Float32Array(triangles);
+ var geometry = this._fill.geometry;
+ var attribute = geometry.getAttribute("position");
+ if (attribute.array.length === positions.length) {
+ attribute.set(positions);
+ attribute.needsUpdate = true;
+ }
+ else {
+ geometry.removeAttribute("position");
+ geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+ }
+ geometry.computeBoundingSphere();
+ };
+ OutlineRenderTag.prototype._updateFillMaterial = function (material) {
+ material.color = new THREE.Color(this._tag.fillColor);
+ material.opacity = this._tag.fillOpacity;
+ material.needsUpdate = true;
+ };
+ OutlineRenderTag.prototype._updateHoleGeometries = function () {
+ var holes3d = this._getHoles3d();
+ if (holes3d.length !== this._holes.length) {
+ throw new Error("Changing the number of holes is not supported.");
+ }
+ for (var i = 0; i < this._holes.length; i++) {
+ var holePoints3d = holes3d[i];
+ var hole = this._holes[i];
+ this._updateLine(hole, holePoints3d);
+ }
+ };
+ OutlineRenderTag.prototype._updateHoleMaterials = function () {
+ for (var _i = 0, _a = this._holes; _i < _a.length; _i++) {
+ var hole = _a[_i];
+ var material = hole.material;
+ this._updateLineBasicMaterial(material);
+ }
+ };
+ OutlineRenderTag.prototype._updateLine = function (line, points3d) {
+ var positions = this._getLinePositions(points3d);
+ var geometry = line.geometry;
+ var attribute = geometry.getAttribute("position");
+ attribute.set(positions);
+ attribute.needsUpdate = true;
+ geometry.computeBoundingSphere();
+ };
+ OutlineRenderTag.prototype._updateOulineGeometry = function () {
+ this._updateLine(this._outline, this._getPoints3d());
+ };
+ OutlineRenderTag.prototype._updateOutlineMaterial = function () {
+ var material = this._outline.material;
+ this._updateLineBasicMaterial(material);
+ };
+ OutlineRenderTag.prototype._updateLineBasicMaterial = function (material) {
+ material.color = new THREE.Color(this._tag.lineColor);
+ material.linewidth = Math.max(this._tag.lineWidth, 1);
+ material.visible = this._tag.lineWidth >= 1 && this._tag.lineOpacity > 0;
+ material.opacity = this._tag.lineOpacity;
+ material.transparent = this._tag.lineOpacity < 1;
+ material.needsUpdate = true;
+ };
+ return OutlineRenderTag;
+}(Component_1.RenderTag));
+exports.OutlineRenderTag = OutlineRenderTag;
+
+
+},{"../../../Component":275,"three":226,"virtual-dom":231}],367:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var Component_1 = require("../../../Component");
+var Viewer_1 = require("../../../Viewer");
+/**
+ * @class OutlineTag
+ *
+ * @classdesc Tag holding properties for visualizing a geometry outline.
+ *
+ * @example
+ * ```
+ * var geometry = new Mapillary.TagComponent.RectGeometry([0.3, 0.3, 0.5, 0.4]);
+ * var tag = new Mapillary.TagComponent.OutlineTag(
+ * "id-1",
+ * geometry
+ * { editable: true, lineColor: 0xff0000 });
+ *
+ * tagComponent.add([tag]);
+ * ```
+ */
+var OutlineTag = /** @class */ (function (_super) {
+ __extends(OutlineTag, _super);
+ /**
+ * Create an outline tag.
+ *
+ * @override
+ * @constructor
+ * @param {string} id - Unique identifier of the tag.
+ * @param {VertexGeometry} geometry - Geometry defining vertices of tag.
+ * @param {IOutlineTagOptions} options - Options defining the visual appearance and
+ * behavior of the outline tag.
+ */
+ function OutlineTag(id, geometry, options) {
+ var _this = _super.call(this, id, geometry) || this;
+ options = !!options ? options : {};
+ var domain = options.domain != null && geometry instanceof Component_1.PolygonGeometry ?
+ options.domain : Component_1.TagDomain.TwoDimensional;
+ var twoDimensionalPolygon = _this._twoDimensionalPolygon(domain, geometry);
+ _this._domain = domain;
+ _this._editable = options.editable == null || twoDimensionalPolygon ? false : options.editable;
+ _this._fillColor = options.fillColor == null ? 0xFFFFFF : options.fillColor;
+ _this._fillOpacity = options.fillOpacity == null ? 0.0 : options.fillOpacity;
+ _this._icon = options.icon === undefined ? null : options.icon;
+ _this._iconFloat = options.iconFloat == null ? Viewer_1.Alignment.Center : options.iconFloat;
+ _this._iconIndex = options.iconIndex == null ? 3 : options.iconIndex;
+ _this._indicateVertices = options.indicateVertices == null ? true : options.indicateVertices;
+ _this._lineColor = options.lineColor == null ? 0xFFFFFF : options.lineColor;
+ _this._lineOpacity = options.lineOpacity == null ? 1 : options.lineOpacity;
+ _this._lineWidth = options.lineWidth == null ? 1 : options.lineWidth;
+ _this._text = options.text === undefined ? null : options.text;
+ _this._textColor = options.textColor == null ? 0xFFFFFF : options.textColor;
+ _this._click$ = new rxjs_1.Subject();
+ _this._click$
+ .subscribe(function (t) {
+ _this.fire(OutlineTag.click, _this);
+ });
+ return _this;
+ }
+ Object.defineProperty(OutlineTag.prototype, "click$", {
+ /**
+ * Click observable.
+ *
+ * @description An observable emitting the tag when the icon of the
+ * tag has been clicked.
+ *
+ * @returns {Observable<Tag>}
+ */
+ get: function () {
+ return this._click$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineTag.prototype, "domain", {
+ /**
+ * Get domain property.
+ *
+ * @description Readonly property that can only be set in constructor.
+ *
+ * @returns Value indicating the domain of the tag.
+ */
+ get: function () {
+ return this._domain;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineTag.prototype, "editable", {
+ /**
+ * Get editable property.
+ * @returns {boolean} Value indicating if tag is editable.
+ */
+ get: function () {
+ return this._editable;
+ },
+ /**
+ * Set editable property.
+ * @param {boolean}
+ *
+ * @fires Tag#changed
+ */
+ set: function (value) {
+ if (this._twoDimensionalPolygon(this._domain, this._geometry)) {
+ return;
+ }
+ this._editable = value;
+ this._notifyChanged$.next(this);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineTag.prototype, "fillColor", {
+ /**
+ * Get fill color property.
+ * @returns {number}
+ */
+ get: function () {
+ return this._fillColor;
+ },
+ /**
+ * Set fill color property.
+ * @param {number}
+ *
+ * @fires Tag#changed
+ */
+ set: function (value) {
+ this._fillColor = value;
+ this._notifyChanged$.next(this);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineTag.prototype, "fillOpacity", {
+ /**
+ * Get fill opacity property.
+ * @returns {number}
+ */
+ get: function () {
+ return this._fillOpacity;
+ },
+ /**
+ * Set fill opacity property.
+ * @param {number}
+ *
+ * @fires Tag#changed
+ */
+ set: function (value) {
+ this._fillOpacity = value;
+ this._notifyChanged$.next(this);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineTag.prototype, "geometry", {
+ /** @inheritdoc */
+ get: function () {
+ return this._geometry;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineTag.prototype, "icon", {
+ /**
+ * Get icon property.
+ * @returns {string}
+ */
+ get: function () {
+ return this._icon;
+ },
+ /**
+ * Set icon property.
+ * @param {string}
+ *
+ * @fires Tag#changed
+ */
+ set: function (value) {
+ this._icon = value;
+ this._notifyChanged$.next(this);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineTag.prototype, "iconFloat", {
+ /**
+ * Get icon float property.
+ * @returns {Alignment}
+ */
+ get: function () {
+ return this._iconFloat;
+ },
+ /**
+ * Set icon float property.
+ * @param {Alignment}
+ *
+ * @fires Tag#changed
+ */
+ set: function (value) {
+ this._iconFloat = value;
+ this._notifyChanged$.next(this);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(OutlineTag.prototype, "iconIndex", {
+ /**
+ * Get icon index property.
+ * @returns {number}