(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return [] } process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],2:[function(require,module,exports){ (function (setImmediate,clearImmediate){ var nextTick = require('process/browser.js').nextTick; var apply = Function.prototype.apply; var slice = Array.prototype.slice; var immediateIds = {}; var nextImmediateId = 0; // DOM APIs, for completeness exports.setTimeout = function() { return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); }; exports.setInterval = function() { return new Timeout(apply.call(setInterval, window, arguments), clearInterval); }; exports.clearTimeout = exports.clearInterval = function(timeout) { timeout.close(); }; function Timeout(id, clearFn) { this._id = id; this._clearFn = clearFn; } Timeout.prototype.unref = Timeout.prototype.ref = function() {}; Timeout.prototype.close = function() { this._clearFn.call(window, this._id); }; // Does not start the time, just sets up the members needed. exports.enroll = function(item, msecs) { clearTimeout(item._idleTimeoutId); item._idleTimeout = msecs; }; exports.unenroll = function(item) { clearTimeout(item._idleTimeoutId); item._idleTimeout = -1; }; exports._unrefActive = exports.active = function(item) { clearTimeout(item._idleTimeoutId); var msecs = item._idleTimeout; if (msecs >= 0) { item._idleTimeoutId = setTimeout(function onTimeout() { if (item._onTimeout) item._onTimeout(); }, msecs); } }; // That's not how node.js implements it but the exposed api is the same. exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { var id = nextImmediateId++; var args = arguments.length < 2 ? false : slice.call(arguments, 1); immediateIds[id] = true; nextTick(function onNextTick() { if (immediateIds[id]) { // fn.call() is faster so we optimize for the common use-case // @see http://jsperf.com/call-apply-segu if (args) { fn.apply(null, args); } else { fn.call(null); } // Prevent ids from leaking exports.clearImmediate(id); } }); return id; }; exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) { delete immediateIds[id]; }; }).call(this,require("timers").setImmediate,require("timers").clearImmediate) },{"process/browser.js":1,"timers":2}],3:[function(require,module,exports){ (function (global,setImmediate){ new function() { function Vnode(tag, key, attrs0, children, text, dom) { return {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: {}, events: undefined, instance: undefined, skip: false} } Vnode.normalize = function(node) { if (Array.isArray(node)) return Vnode("[", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined) if (node != null && typeof node !== "object") return Vnode("#", undefined, undefined, node === false ? "" : node, undefined, undefined) return node } Vnode.normalizeChildren = function normalizeChildren(children) { for (var i = 0; i < children.length; i++) { children[i] = Vnode.normalize(children[i]) } return children } var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g var selectorCache = {} function hyperscript(selector) { if (selector == null || typeof selector !== "string" && typeof selector.view !== "function") { throw Error("The selector must be either a string or a component."); } if (typeof selector === "string" && selectorCache[selector] === undefined) { var match, tag, classes = [], attributes = {} while (match = selectorParser.exec(selector)) { var type = match[1], value = match[2] if (type === "" && value !== "") tag = value else if (type === "#") attributes.id = value else if (type === ".") classes.push(value) else if (match[3][0] === "[") { var attrValue = match[6] if (attrValue) attrValue = attrValue.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\") if (match[4] === "class") classes.push(attrValue) else attributes[match[4]] = attrValue || true } } if (classes.length > 0) attributes.className = classes.join(" ") selectorCache[selector] = function(attrs, children) { var hasAttrs = false, childList, text var className = attrs.className || attrs.class for (var key in attributes) attrs[key] = attributes[key] if (className !== undefined) { if (attrs.class !== undefined) { attrs.class = undefined attrs.className = className } if (attributes.className !== undefined) attrs.className = attributes.className + " " + className } for (var key in attrs) { if (key !== "key") { hasAttrs = true break } } if (Array.isArray(children) && children.length == 1 && children[0] != null && children[0].tag === "#") text = children[0].children else childList = children return Vnode(tag || "div", attrs.key, hasAttrs ? attrs : undefined, childList, text, undefined) } } var attrs, children, childrenIndex if (arguments[1] == null || typeof arguments[1] === "object" && arguments[1].tag === undefined && !Array.isArray(arguments[1])) { attrs = arguments[1] childrenIndex = 2 } else childrenIndex = 1 if (arguments.length === childrenIndex + 1) { children = Array.isArray(arguments[childrenIndex]) ? arguments[childrenIndex] : [arguments[childrenIndex]] } else { children = [] for (var i = childrenIndex; i < arguments.length; i++) children.push(arguments[i]) } if (typeof selector === "string") return selectorCache[selector](attrs || {}, Vnode.normalizeChildren(children)) return Vnode(selector, attrs && attrs.key, attrs || {}, Vnode.normalizeChildren(children), undefined, undefined) } hyperscript.trust = function(html) { if (html == null) html = "" return Vnode("<", undefined, undefined, html, undefined, undefined) } hyperscript.fragment = function(attrs1, children) { return Vnode("[", attrs1.key, attrs1, Vnode.normalizeChildren(children), undefined, undefined) } var m = hyperscript /** @constructor */ var PromisePolyfill = function(executor) { if (!(this instanceof PromisePolyfill)) throw new Error("Promise must be called with `new`") if (typeof executor !== "function") throw new TypeError("executor must be a function") var self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false) var instance = self._instance = {resolvers: resolvers, rejectors: rejectors} var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout function handler(list, shouldAbsorb) { return function execute(value) { var then try { if (shouldAbsorb && value != null && (typeof value === "object" || typeof value === "function") && typeof (then = value.then) === "function") { if (value === self) throw new TypeError("Promise can't be resolved w/ itself") executeOnce(then.bind(value)) } else { callAsync(function() { if (!shouldAbsorb && list.length === 0) console.error("Possible unhandled promise rejection:", value) for (var i = 0; i < list.length; i++) list[i](value) resolvers.length = 0, rejectors.length = 0 instance.state = shouldAbsorb instance.retry = function() {execute(value)} }) } } catch (e) { rejectCurrent(e) } } } function executeOnce(then) { var runs = 0 function run(fn) { return function(value) { if (runs++ > 0) return fn(value) } } var onerror = run(rejectCurrent) try {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)} } executeOnce(executor) } PromisePolyfill.prototype.then = function(onFulfilled, onRejection) { var self = this, instance = self._instance function handle(callback, list, next, state) { list.push(function(value) { if (typeof callback !== "function") next(value) else try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)} }) if (typeof instance.retry === "function" && state === instance.state) instance.retry() } var resolveNext, rejectNext var promise = new PromisePolyfill(function(resolve, reject) {resolveNext = resolve, rejectNext = reject}) handle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false) return promise } PromisePolyfill.prototype.catch = function(onRejection) { return this.then(null, onRejection) } PromisePolyfill.resolve = function(value) { if (value instanceof PromisePolyfill) return value return new PromisePolyfill(function(resolve) {resolve(value)}) } PromisePolyfill.reject = function(value) { return new PromisePolyfill(function(resolve, reject) {reject(value)}) } PromisePolyfill.all = function(list) { return new PromisePolyfill(function(resolve, reject) { var total = list.length, count = 0, values = [] if (list.length === 0) resolve([]) else for (var i = 0; i < list.length; i++) { (function(i) { function consume(value) { count++ values[i] = value if (count === total) resolve(values) } if (list[i] != null && (typeof list[i] === "object" || typeof list[i] === "function") && typeof list[i].then === "function") { list[i].then(consume, reject) } else consume(list[i]) })(i) } }) } PromisePolyfill.race = function(list) { return new PromisePolyfill(function(resolve, reject) { for (var i = 0; i < list.length; i++) { list[i].then(resolve, reject) } }) } if (typeof window !== "undefined") { if (typeof window.Promise === "undefined") window.Promise = PromisePolyfill var PromisePolyfill = window.Promise } else if (typeof global !== "undefined") { if (typeof global.Promise === "undefined") global.Promise = PromisePolyfill var PromisePolyfill = global.Promise } else { } var buildQueryString = function(object) { if (Object.prototype.toString.call(object) !== "[object Object]") return "" var args = [] for (var key0 in object) { destructure(key0, object[key0]) } return args.join("&") function destructure(key0, value) { if (Array.isArray(value)) { for (var i = 0; i < value.length; i++) { destructure(key0 + "[" + i + "]", value[i]) } } else if (Object.prototype.toString.call(value) === "[object Object]") { for (var i in value) { destructure(key0 + "[" + i + "]", value[i]) } } else args.push(encodeURIComponent(key0) + (value != null && value !== "" ? "=" + encodeURIComponent(value) : "")) } } var _8 = function($window, Promise) { var callbackCount = 0 var oncompletion function setCompletionCallback(callback) {oncompletion = callback} function finalizer() { var count = 0 function complete() {if (--count === 0 && typeof oncompletion === "function") oncompletion()} return function finalize(promise0) { var then0 = promise0.then promise0.then = function() { count++ var next = then0.apply(promise0, arguments) next.then(complete, function(e) { complete() if (count === 0) throw e }) return finalize(next) } return promise0 } } function normalize(args, extra) { if (typeof args === "string") { var url = args args = extra || {} if (args.url == null) args.url = url } return args } function request(args, extra) { var finalize = finalizer() args = normalize(args, extra) var promise0 = new Promise(function(resolve, reject) { if (args.method == null) args.method = "GET" args.method = args.method.toUpperCase() var useBody = typeof args.useBody === "boolean" ? args.useBody : args.method !== "GET" && args.method !== "TRACE" if (typeof args.serialize !== "function") args.serialize = typeof FormData !== "undefined" && args.data instanceof FormData ? function(value) {return value} : JSON.stringify if (typeof args.deserialize !== "function") args.deserialize = deserialize if (typeof args.extract !== "function") args.extract = extract args.url = interpolate(args.url, args.data) if (useBody) args.data = args.serialize(args.data) else args.url = assemble(args.url, args.data) var xhr = new $window.XMLHttpRequest() xhr.open(args.method, args.url, typeof args.async === "boolean" ? args.async : true, typeof args.user === "string" ? args.user : undefined, typeof args.password === "string" ? args.password : undefined) if (args.serialize === JSON.stringify && useBody) { xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8") } if (args.deserialize === deserialize) { xhr.setRequestHeader("Accept", "application/json, text/*") } if (args.withCredentials) xhr.withCredentials = args.withCredentials for (var key in args.headers) if ({}.hasOwnProperty.call(args.headers, key)) { xhr.setRequestHeader(key, args.headers[key]) } if (typeof args.config === "function") xhr = args.config(xhr, args) || xhr xhr.onreadystatechange = function() { // Don't throw errors on xhr.abort(). XMLHttpRequests ends up in a state of // xhr.status == 0 and xhr.readyState == 4 if aborted after open, but before completion. if (xhr.status && xhr.readyState === 4) { try { var response = (args.extract !== extract) ? args.extract(xhr, args) : args.deserialize(args.extract(xhr, args)) if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { resolve(cast(args.type, response)) } else { var error = new Error(xhr.responseText) for (var key in response) error[key] = response[key] reject(error) } } catch (e) { reject(e) } } } if (useBody && (args.data != null)) xhr.send(args.data) else xhr.send() }) return args.background === true ? promise0 : finalize(promise0) } function jsonp(args, extra) { var finalize = finalizer() args = normalize(args, extra) var promise0 = new Promise(function(resolve, reject) { var callbackName = args.callbackName || "_mithril_" + Math.round(Math.random() * 1e16) + "_" + callbackCount++ var script = $window.document.createElement("script") $window[callbackName] = function(data) { script.parentNode.removeChild(script) resolve(cast(args.type, data)) delete $window[callbackName] } script.onerror = function() { script.parentNode.removeChild(script) reject(new Error("JSONP request failed")) delete $window[callbackName] } if (args.data == null) args.data = {} args.url = interpolate(args.url, args.data) args.data[args.callbackKey || "callback"] = callbackName script.src = assemble(args.url, args.data) $window.document.documentElement.appendChild(script) }) return args.background === true? promise0 : finalize(promise0) } function interpolate(url, data) { if (data == null) return url var tokens = url.match(/:[^\/]+/gi) || [] for (var i = 0; i < tokens.length; i++) { var key = tokens[i].slice(1) if (data[key] != null) { url = url.replace(tokens[i], data[key]) } } return url } function assemble(url, data) { var querystring = buildQueryString(data) if (querystring !== "") { var prefix = url.indexOf("?") < 0 ? "?" : "&" url += prefix + querystring } return url } function deserialize(data) { try {return data !== "" ? JSON.parse(data) : null} catch (e) {throw new Error(data)} } function extract(xhr) {return xhr.responseText} function cast(type0, data) { if (typeof type0 === "function") { if (Array.isArray(data)) { for (var i = 0; i < data.length; i++) { data[i] = new type0(data[i]) } } else return new type0(data) } return data } return {request: request, jsonp: jsonp, setCompletionCallback: setCompletionCallback} } var requestService = _8(window, PromisePolyfill) var coreRenderer = function($window) { var $doc = $window.document var $emptyFragment = $doc.createDocumentFragment() var onevent function setEventCallback(callback) {return onevent = callback} //create function createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) { for (var i = start; i < end; i++) { var vnode = vnodes[i] if (vnode != null) { insertNode(parent, createNode(vnode, hooks, ns), nextSibling) } } } function createNode(vnode, hooks, ns) { var tag = vnode.tag if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks) if (typeof tag === "string") { switch (tag) { case "#": return createText(vnode) case "<": return createHTML(vnode) case "[": return createFragment(vnode, hooks, ns) default: return createElement(vnode, hooks, ns) } } else return createComponent(vnode, hooks, ns) } function createText(vnode) { return vnode.dom = $doc.createTextNode(vnode.children) } function createHTML(vnode) { var match1 = vnode.children.match(/^\s*?<(\w+)/im) || [] var parent = {caption: "table", thead: "table", tbody: "table", tfoot: "table", tr: "tbody", th: "tr", td: "tr", colgroup: "table", col: "colgroup"}[match1[1]] || "div" var temp = $doc.createElement(parent) temp.innerHTML = vnode.children vnode.dom = temp.firstChild vnode.domSize = temp.childNodes.length var fragment = $doc.createDocumentFragment() var child while (child = temp.firstChild) { fragment.appendChild(child) } return fragment } function createFragment(vnode, hooks, ns) { var fragment = $doc.createDocumentFragment() if (vnode.children != null) { var children = vnode.children createNodes(fragment, children, 0, children.length, hooks, null, ns) } vnode.dom = fragment.firstChild vnode.domSize = fragment.childNodes.length return fragment } function createElement(vnode, hooks, ns) { var tag = vnode.tag switch (vnode.tag) { case "svg": ns = "http://www.w3.org/2000/svg"; break case "math": ns = "http://www.w3.org/1998/Math/MathML"; break } var attrs2 = vnode.attrs var is = attrs2 && attrs2.is var element = ns ? is ? $doc.createElementNS(ns, tag, {is: is}) : $doc.createElementNS(ns, tag) : is ? $doc.createElement(tag, {is: is}) : $doc.createElement(tag) vnode.dom = element if (attrs2 != null) { setAttrs(vnode, attrs2, ns) } if (vnode.attrs != null && vnode.attrs.contenteditable != null) { setContentEditable(vnode) } else { if (vnode.text != null) { if (vnode.text !== "") element.textContent = vnode.text else vnode.children = [Vnode("#", undefined, undefined, vnode.text, undefined, undefined)] } if (vnode.children != null) { var children = vnode.children createNodes(element, children, 0, children.length, hooks, null, ns) setLateAttrs(vnode) } } return element } function createComponent(vnode, hooks, ns) { vnode.state = Object.create(vnode.tag) var view = vnode.tag.view if (view.reentrantLock != null) return $emptyFragment view.reentrantLock = true initLifecycle(vnode.tag, vnode, hooks) vnode.instance = Vnode.normalize(view.call(vnode.state, vnode)) view.reentrantLock = null if (vnode.instance != null) { if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as arguments") var element = createNode(vnode.instance, hooks, ns) vnode.dom = vnode.instance.dom vnode.domSize = vnode.dom != null ? vnode.instance.domSize : 0 return element } else { vnode.domSize = 0 return $emptyFragment } } //update function updateNodes(parent, old, vnodes, hooks, nextSibling, ns) { if (old === vnodes || old == null && vnodes == null) return else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, undefined) else if (vnodes == null) removeNodes(old, 0, old.length, vnodes) else { if (old.length === vnodes.length) { var isUnkeyed = false for (var i = 0; i < vnodes.length; i++) { if (vnodes[i] != null && old[i] != null) { isUnkeyed = vnodes[i].key == null && old[i].key == null break } } if (isUnkeyed) { for (var i = 0; i < old.length; i++) { if (old[i] === vnodes[i]) continue else if (old[i] == null && vnodes[i] != null) insertNode(parent, createNode(vnodes[i], hooks, ns), getNextSibling(old, i + 1, nextSibling)) else if (vnodes[i] == null) removeNodes(old, i, i + 1, vnodes) else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), false, ns) } return } } var recycling = isRecyclable(old, vnodes) if (recycling) old = old.concat(old.pool) var oldStart = 0, start = 0, oldEnd = old.length - 1, end = vnodes.length - 1, map while (oldEnd >= oldStart && end >= start) { var o = old[oldStart], v = vnodes[start] if (o === v && !recycling) oldStart++, start++ else if (o == null) oldStart++ else if (v == null) start++ else if (o.key === v.key) { oldStart++, start++ updateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), recycling, ns) if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling) } else { var o = old[oldEnd] if (o === v && !recycling) oldEnd--, start++ else if (o == null) oldEnd-- else if (v == null) start++ else if (o.key === v.key) { updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns) if (recycling || start < end) insertNode(parent, toFragment(o), getNextSibling(old, oldStart, nextSibling)) oldEnd--, start++ } else break } } while (oldEnd >= oldStart && end >= start) { var o = old[oldEnd], v = vnodes[end] if (o === v && !recycling) oldEnd--, end-- else if (o == null) oldEnd-- else if (v == null) end-- else if (o.key === v.key) { updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns) if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling) if (o.dom != null) nextSibling = o.dom oldEnd--, end-- } else { if (!map) map = getKeyMap(old, oldEnd) if (v != null) { var oldIndex = map[v.key] if (oldIndex != null) { var movable = old[oldIndex] updateNode(parent, movable, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns) insertNode(parent, toFragment(movable), nextSibling) old[oldIndex].skip = true if (movable.dom != null) nextSibling = movable.dom } else { var dom = createNode(v, hooks, undefined) insertNode(parent, dom, nextSibling) nextSibling = dom } } end-- } if (end < start) break } createNodes(parent, vnodes, start, end + 1, hooks, nextSibling, ns) removeNodes(old, oldStart, oldEnd + 1, vnodes) } } function updateNode(parent, old, vnode, hooks, nextSibling, recycling, ns) { var oldTag = old.tag, tag = vnode.tag if (oldTag === tag) { vnode.state = old.state vnode.events = old.events if (shouldUpdate(vnode, old)) return if (vnode.attrs != null) { updateLifecycle(vnode.attrs, vnode, hooks, recycling) } if (typeof oldTag === "string") { switch (oldTag) { case "#": updateText(old, vnode); break case "<": updateHTML(parent, old, vnode, nextSibling); break case "[": updateFragment(parent, old, vnode, hooks, nextSibling, ns); break default: updateElement(old, vnode, hooks, ns) } } else updateComponent(parent, old, vnode, hooks, nextSibling, recycling, ns) } else { removeNode(old, null) insertNode(parent, createNode(vnode, hooks, ns), nextSibling) } } function updateText(old, vnode) { if (old.children.toString() !== vnode.children.toString()) { old.dom.nodeValue = vnode.children } vnode.dom = old.dom } function updateHTML(parent, old, vnode, nextSibling) { if (old.children !== vnode.children) { toFragment(old) insertNode(parent, createHTML(vnode), nextSibling) } else vnode.dom = old.dom, vnode.domSize = old.domSize } function updateFragment(parent, old, vnode, hooks, nextSibling, ns) { updateNodes(parent, old.children, vnode.children, hooks, nextSibling, ns) var domSize = 0, children = vnode.children vnode.dom = null if (children != null) { for (var i = 0; i < children.length; i++) { var child = children[i] if (child != null && child.dom != null) { if (vnode.dom == null) vnode.dom = child.dom domSize += child.domSize || 1 } } if (domSize !== 1) vnode.domSize = domSize } } function updateElement(old, vnode, hooks, ns) { var element = vnode.dom = old.dom switch (vnode.tag) { case "svg": ns = "http://www.w3.org/2000/svg"; break case "math": ns = "http://www.w3.org/1998/Math/MathML"; break } if (vnode.tag === "textarea") { if (vnode.attrs == null) vnode.attrs = {} if (vnode.text != null) { vnode.attrs.value = vnode.text //FIXME handle0 multiple children vnode.text = undefined } } updateAttrs(vnode, old.attrs, vnode.attrs, ns) if (vnode.attrs != null && vnode.attrs.contenteditable != null) { setContentEditable(vnode) } else if (old.text != null && vnode.text != null && vnode.text !== "") { if (old.text.toString() !== vnode.text.toString()) old.dom.firstChild.nodeValue = vnode.text } else { if (old.text != null) old.children = [Vnode("#", undefined, undefined, old.text, undefined, old.dom.firstChild)] if (vnode.text != null) vnode.children = [Vnode("#", undefined, undefined, vnode.text, undefined, undefined)] updateNodes(element, old.children, vnode.children, hooks, null, ns) } } function updateComponent(parent, old, vnode, hooks, nextSibling, recycling, ns) { vnode.instance = Vnode.normalize(vnode.tag.view.call(vnode.state, vnode)) updateLifecycle(vnode.tag, vnode, hooks, recycling) if (vnode.instance != null) { if (old.instance == null) insertNode(parent, createNode(vnode.instance, hooks, ns), nextSibling) else updateNode(parent, old.instance, vnode.instance, hooks, nextSibling, recycling, ns) vnode.dom = vnode.instance.dom vnode.domSize = vnode.instance.domSize } else if (old.instance != null) { removeNode(old.instance, null) vnode.dom = undefined vnode.domSize = 0 } else { vnode.dom = old.dom vnode.domSize = old.domSize } } function isRecyclable(old, vnodes) { if (old.pool != null && Math.abs(old.pool.length - vnodes.length) <= Math.abs(old.length - vnodes.length)) { var oldChildrenLength = old[0] && old[0].children && old[0].children.length || 0 var poolChildrenLength = old.pool[0] && old.pool[0].children && old.pool[0].children.length || 0 var vnodesChildrenLength = vnodes[0] && vnodes[0].children && vnodes[0].children.length || 0 if (Math.abs(poolChildrenLength - vnodesChildrenLength) <= Math.abs(oldChildrenLength - vnodesChildrenLength)) { return true } } return false } function getKeyMap(vnodes, end) { var map = {}, i = 0 for (var i = 0; i < end; i++) { var vnode = vnodes[i] if (vnode != null) { var key2 = vnode.key if (key2 != null) map[key2] = i } } return map } function toFragment(vnode) { var count0 = vnode.domSize if (count0 != null || vnode.dom == null) { var fragment = $doc.createDocumentFragment() if (count0 > 0) { var dom = vnode.dom while (--count0) fragment.appendChild(dom.nextSibling) fragment.insertBefore(dom, fragment.firstChild) } return fragment } else return vnode.dom } function getNextSibling(vnodes, i, nextSibling) { for (; i < vnodes.length; i++) { if (vnodes[i] != null && vnodes[i].dom != null) return vnodes[i].dom } return nextSibling } function insertNode(parent, dom, nextSibling) { if (nextSibling && nextSibling.parentNode) parent.insertBefore(dom, nextSibling) else parent.appendChild(dom) } function setContentEditable(vnode) { var children = vnode.children if (children != null && children.length === 1 && children[0].tag === "<") { var content = children[0].children if (vnode.dom.innerHTML !== content) vnode.dom.innerHTML = content } else if (vnode.text != null || children != null && children.length !== 0) throw new Error("Child node of a contenteditable must be trusted") } //remove function removeNodes(vnodes, start, end, context) { for (var i = start; i < end; i++) { var vnode = vnodes[i] if (vnode != null) { if (vnode.skip) vnode.skip = false else removeNode(vnode, context) } } } function removeNode(vnode, context) { var expected = 1, called = 0 if (vnode.attrs && vnode.attrs.onbeforeremove) { var result = vnode.attrs.onbeforeremove.call(vnode.state, vnode) if (result != null && typeof result.then === "function") { expected++ result.then(continuation, continuation) } } if (typeof vnode.tag !== "string" && vnode.tag.onbeforeremove) { var result = vnode.tag.onbeforeremove.call(vnode.state, vnode) if (result != null && typeof result.then === "function") { expected++ result.then(continuation, continuation) } } continuation() function continuation() { if (++called === expected) { onremove(vnode) if (vnode.dom) { var count0 = vnode.domSize || 1 if (count0 > 1) { var dom = vnode.dom while (--count0) { removeNodeFromDOM(dom.nextSibling) } } removeNodeFromDOM(vnode.dom) if (context != null && vnode.domSize == null && !hasIntegrationMethods(vnode.attrs) && typeof vnode.tag === "string") { //TODO test custom elements if (!context.pool) context.pool = [vnode] else context.pool.push(vnode) } } } } } function removeNodeFromDOM(node) { var parent = node.parentNode if (parent != null) parent.removeChild(node) } function onremove(vnode) { if (vnode.attrs && vnode.attrs.onremove) vnode.attrs.onremove.call(vnode.state, vnode) if (typeof vnode.tag !== "string" && vnode.tag.onremove) vnode.tag.onremove.call(vnode.state, vnode) if (vnode.instance != null) onremove(vnode.instance) else { var children = vnode.children if (Array.isArray(children)) { for (var i = 0; i < children.length; i++) { var child = children[i] if (child != null) onremove(child) } } } } //attrs2 function setAttrs(vnode, attrs2, ns) { for (var key2 in attrs2) { setAttr(vnode, key2, null, attrs2[key2], ns) } } function setAttr(vnode, key2, old, value, ns) { var element = vnode.dom if (key2 === "key" || key2 === "is" || (old === value && !isFormAttribute(vnode, key2)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key2)) return var nsLastIndex = key2.indexOf(":") if (nsLastIndex > -1 && key2.substr(0, nsLastIndex) === "xlink") { element.setAttributeNS("http://www.w3.org/1999/xlink", key2.slice(nsLastIndex + 1), value) } else if (key2[0] === "o" && key2[1] === "n" && typeof value === "function") updateEvent(vnode, key2, value) else if (key2 === "style") updateStyle(element, old, value) else if (key2 in element && !isAttribute(key2) && ns === undefined && !isCustomElement(vnode)) { //setting input[value] to same value by typing on focused element moves cursor to end in Chrome if (vnode.tag === "input" && key2 === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return //setting select[value] to same value while having select open blinks select dropdown in Chrome if (vnode.tag === "select" && key2 === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return //setting option[value] to same value while having select open blinks select dropdown in Chrome if (vnode.tag === "option" && key2 === "value" && vnode.dom.value === value) return element[key2] = value } else { if (typeof value === "boolean") { if (value) element.setAttribute(key2, "") else element.removeAttribute(key2) } else element.setAttribute(key2 === "className" ? "class" : key2, value) } } function setLateAttrs(vnode) { var attrs2 = vnode.attrs if (vnode.tag === "select" && attrs2 != null) { if ("value" in attrs2) setAttr(vnode, "value", null, attrs2.value, undefined) if ("selectedIndex" in attrs2) setAttr(vnode, "selectedIndex", null, attrs2.selectedIndex, undefined) } } function updateAttrs(vnode, old, attrs2, ns) { if (attrs2 != null) { for (var key2 in attrs2) { setAttr(vnode, key2, old && old[key2], attrs2[key2], ns) } } if (old != null) { for (var key2 in old) { if (attrs2 == null || !(key2 in attrs2)) { if (key2 === "className") key2 = "class" if (key2[0] === "o" && key2[1] === "n" && !isLifecycleMethod(key2)) updateEvent(vnode, key2, undefined) else if (key2 !== "key") vnode.dom.removeAttribute(key2) } } } } function isFormAttribute(vnode, attr) { return attr === "value" || attr === "checked" || attr === "selectedIndex" || attr === "selected" && vnode.dom === $doc.activeElement } function isLifecycleMethod(attr) { return attr === "oninit" || attr === "oncreate" || attr === "onupdate" || attr === "onremove" || attr === "onbeforeremove" || attr === "onbeforeupdate" } function isAttribute(attr) { return attr === "href" || attr === "list" || attr === "form" || attr === "width" || attr === "height"// || attr === "type" } function isCustomElement(vnode){ return vnode.attrs.is || vnode.tag.indexOf("-") > -1 } function hasIntegrationMethods(source) { return source != null && (source.oncreate || source.onupdate || source.onbeforeremove || source.onremove) } //style function updateStyle(element, old, style) { if (old === style) element.style.cssText = "", old = null if (style == null) element.style.cssText = "" else if (typeof style === "string") element.style.cssText = style else { if (typeof old === "string") element.style.cssText = "" for (var key2 in style) { element.style[key2] = style[key2] } if (old != null && typeof old !== "string") { for (var key2 in old) { if (!(key2 in style)) element.style[key2] = "" } } } } //event function updateEvent(vnode, key2, value) { var element = vnode.dom var callback = typeof onevent !== "function" ? value : function(e) { var result = value.call(element, e) onevent.call(element, e) return result } if (key2 in element) element[key2] = typeof value === "function" ? callback : null else { var eventName = key2.slice(2) if (vnode.events === undefined) vnode.events = {} if (vnode.events[key2] === callback) return if (vnode.events[key2] != null) element.removeEventListener(eventName, vnode.events[key2], false) if (typeof value === "function") { vnode.events[key2] = callback element.addEventListener(eventName, vnode.events[key2], false) } } } //lifecycle function initLifecycle(source, vnode, hooks) { if (typeof source.oninit === "function") source.oninit.call(vnode.state, vnode) if (typeof source.oncreate === "function") hooks.push(source.oncreate.bind(vnode.state, vnode)) } function updateLifecycle(source, vnode, hooks, recycling) { if (recycling) initLifecycle(source, vnode, hooks) else if (typeof source.onupdate === "function") hooks.push(source.onupdate.bind(vnode.state, vnode)) } function shouldUpdate(vnode, old) { var forceVnodeUpdate, forceComponentUpdate if (vnode.attrs != null && typeof vnode.attrs.onbeforeupdate === "function") forceVnodeUpdate = vnode.attrs.onbeforeupdate.call(vnode.state, vnode, old) if (typeof vnode.tag !== "string" && typeof vnode.tag.onbeforeupdate === "function") forceComponentUpdate = vnode.tag.onbeforeupdate.call(vnode.state, vnode, old) if (!(forceVnodeUpdate === undefined && forceComponentUpdate === undefined) && !forceVnodeUpdate && !forceComponentUpdate) { vnode.dom = old.dom vnode.domSize = old.domSize vnode.instance = old.instance return true } return false } function render(dom, vnodes) { if (!dom) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.") var hooks = [] var active = $doc.activeElement // First time0 rendering into a node clears it out if (dom.vnodes == null) dom.textContent = "" if (!Array.isArray(vnodes)) vnodes = [vnodes] updateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), hooks, null, undefined) dom.vnodes = vnodes for (var i = 0; i < hooks.length; i++) hooks[i]() if ($doc.activeElement !== active) active.focus() } return {render: render, setEventCallback: setEventCallback} } function throttle(callback) { //60fps translates to 16.6ms, round it down since setTimeout requires int var time = 16 var last = 0, pending = null var timeout = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout return function() { var now = Date.now() if (last === 0 || now - last >= time) { last = now callback() } else if (pending === null) { pending = timeout(function() { pending = null callback() last = Date.now() }, time - (now - last)) } } } var _11 = function($window) { var renderService = coreRenderer($window) renderService.setEventCallback(function(e) { if (e.redraw !== false) redraw() }) var callbacks = [] function subscribe(key1, callback) { unsubscribe(key1) callbacks.push(key1, throttle(callback)) } function unsubscribe(key1) { var index = callbacks.indexOf(key1) if (index > -1) callbacks.splice(index, 2) } function redraw() { for (var i = 1; i < callbacks.length; i += 2) { callbacks[i]() } } return {subscribe: subscribe, unsubscribe: unsubscribe, redraw: redraw, render: renderService.render} } var redrawService = _11(window) requestService.setCompletionCallback(redrawService.redraw) var _16 = function(redrawService0) { return function(root, component) { if (component === null) { redrawService0.render(root, []) redrawService0.unsubscribe(root) return } if (component.view == null) throw new Error("m.mount(element, component) expects a component, not a vnode") var run0 = function() { redrawService0.render(root, Vnode(component)) } redrawService0.subscribe(root, run0) redrawService0.redraw() } } m.mount = _16(redrawService) var Promise = PromisePolyfill var parseQueryString = function(string) { if (string === "" || string == null) return {} if (string.charAt(0) === "?") string = string.slice(1) var entries = string.split("&"), data0 = {}, counters = {} for (var i = 0; i < entries.length; i++) { var entry = entries[i].split("=") var key5 = decodeURIComponent(entry[0]) var value = entry.length === 2 ? decodeURIComponent(entry[1]) : "" if (value === "true") value = true else if (value === "false") value = false var levels = key5.split(/\]\[?|\[/) var cursor = data0 if (key5.indexOf("[") > -1) levels.pop() for (var j = 0; j < levels.length; j++) { var level = levels[j], nextLevel = levels[j + 1] var isNumber = nextLevel == "" || !isNaN(parseInt(nextLevel, 10)) var isValue = j === levels.length - 1 if (level === "") { var key5 = levels.slice(0, j).join() if (counters[key5] == null) counters[key5] = 0 level = counters[key5]++ } if (cursor[level] == null) { cursor[level] = isValue ? value : isNumber ? [] : {} } cursor = cursor[level] } } return data0 } var coreRouter = function($window) { var supportsPushState = typeof $window.history.pushState === "function" var callAsync0 = typeof setImmediate === "function" ? setImmediate : setTimeout function normalize1(fragment0) { var data = $window.location[fragment0].replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent) if (fragment0 === "pathname" && data[0] !== "/") data = "/" + data return data } var asyncId function debounceAsync(callback0) { return function() { if (asyncId != null) return asyncId = callAsync0(function() { asyncId = null callback0() }) } } function parsePath(path, queryData, hashData) { var queryIndex = path.indexOf("?") var hashIndex = path.indexOf("#") var pathEnd = queryIndex > -1 ? queryIndex : hashIndex > -1 ? hashIndex : path.length if (queryIndex > -1) { var queryEnd = hashIndex > -1 ? hashIndex : path.length var queryParams = parseQueryString(path.slice(queryIndex + 1, queryEnd)) for (var key4 in queryParams) queryData[key4] = queryParams[key4] } if (hashIndex > -1) { var hashParams = parseQueryString(path.slice(hashIndex + 1)) for (var key4 in hashParams) hashData[key4] = hashParams[key4] } return path.slice(0, pathEnd) } var router = {prefix: "#!"} router.getPath = function() { var type2 = router.prefix.charAt(0) switch (type2) { case "#": return normalize1("hash").slice(router.prefix.length) case "?": return normalize1("search").slice(router.prefix.length) + normalize1("hash") default: return normalize1("pathname").slice(router.prefix.length) + normalize1("search") + normalize1("hash") } } router.setPath = function(path, data, options) { var queryData = {}, hashData = {} path = parsePath(path, queryData, hashData) if (data != null) { for (var key4 in data) queryData[key4] = data[key4] path = path.replace(/:([^\/]+)/g, function(match2, token) { delete queryData[token] return data[token] }) } var query = buildQueryString(queryData) if (query) path += "?" + query var hash = buildQueryString(hashData) if (hash) path += "#" + hash if (supportsPushState) { var state = options ? options.state : null var title = options ? options.title : null $window.onpopstate() if (options && options.replace) $window.history.replaceState(state, title, router.prefix + path) else $window.history.pushState(state, title, router.prefix + path) } else $window.location.href = router.prefix + path } router.defineRoutes = function(routes, resolve, reject) { function resolveRoute() { var path = router.getPath() var params = {} var pathname = parsePath(path, params, params) var state = $window.history.state if (state != null) { for (var k in state) params[k] = state[k] } for (var route0 in routes) { var matcher = new RegExp("^" + route0.replace(/:[^\/]+?\.{3}/g, "(.*?)").replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$") if (matcher.test(pathname)) { pathname.replace(matcher, function() { var keys = route0.match(/:[^\/]+/g) || [] var values = [].slice.call(arguments, 1, -2) for (var i = 0; i < keys.length; i++) { params[keys[i].replace(/:|\./g, "")] = decodeURIComponent(values[i]) } resolve(routes[route0], params, path, route0) }) return } } reject(path, params) } if (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute) else if (router.prefix.charAt(0) === "#") $window.onhashchange = resolveRoute resolveRoute() } return router } var _20 = function($window, redrawService0) { var routeService = coreRouter($window) var identity = function(v) {return v} var render1, component, attrs3, currentPath, lastUpdate var route = function(root, defaultRoute, routes) { if (root == null) throw new Error("Ensure the DOM element that was passed to `m.route` is not undefined") var run1 = function() { if (render1 != null) redrawService0.render(root, render1(Vnode(component, attrs3.key, attrs3))) } var bail = function() { routeService.setPath(defaultRoute, null, {replace: true}) } routeService.defineRoutes(routes, function(payload, params, path) { var update = lastUpdate = function(routeResolver, comp) { if (update !== lastUpdate) return component = comp != null && typeof comp.view === "function" ? comp : "div", attrs3 = params, currentPath = path, lastUpdate = null render1 = (routeResolver.render || identity).bind(routeResolver) run1() } if (payload.view) update({}, payload) else { if (payload.onmatch) { Promise.resolve(payload.onmatch(params, path)).then(function(resolved) { update(payload, resolved) }, bail) } else update(payload, "div") } }, bail) redrawService0.subscribe(root, run1) } route.set = function(path, data, options) { if (lastUpdate != null) options = {replace: true} lastUpdate = null routeService.setPath(path, data, options) } route.get = function() {return currentPath} route.prefix = function(prefix0) {routeService.prefix = prefix0} route.link = function(vnode1) { vnode1.dom.setAttribute("href", routeService.prefix + vnode1.attrs.href) vnode1.dom.onclick = function(e) { if (e.ctrlKey || e.metaKey || e.shiftKey || e.which === 2) return e.preventDefault() e.redraw = false var href = this.getAttribute("href") if (href.indexOf(routeService.prefix) === 0) href = href.slice(routeService.prefix.length) route.set(href, undefined, undefined) } } route.param = function(key3) { if(typeof attrs3 !== "undefined" && typeof key3 !== "undefined") return attrs3[key3] return attrs3 } return route } m.route = _20(window, redrawService) m.withAttr = function(attrName, callback1, context) { return function(e) { callback1.call(context || this, attrName in e.currentTarget ? e.currentTarget[attrName] : e.currentTarget.getAttribute(attrName)) } } var _28 = coreRenderer(window) m.render = _28.render m.redraw = redrawService.redraw m.request = requestService.request m.jsonp = requestService.jsonp m.parseQueryString = parseQueryString m.buildQueryString = buildQueryString m.version = "1.0.0" m.vnode = Vnode if (typeof module !== "undefined") module["exports"] = m else window.m = m } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("timers").setImmediate) },{"timers":2}],4:[function(require,module,exports){ /*! @preserve * numeral.js * version : 2.0.6 * author : Adam Draper * license : MIT * http://adamwdraper.github.com/Numeral-js/ */ (function (global, factory) { if (typeof define === 'function' && define.amd) { define(factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { global.numeral = factory(); } }(this, function () { /************************************ Variables ************************************/ var numeral, _, VERSION = '2.0.6', formats = {}, locales = {}, defaults = { currentLocale: 'en', zeroFormat: null, nullFormat: null, defaultFormat: '0,0', scalePercentBy100: true }, options = { currentLocale: defaults.currentLocale, zeroFormat: defaults.zeroFormat, nullFormat: defaults.nullFormat, defaultFormat: defaults.defaultFormat, scalePercentBy100: defaults.scalePercentBy100 }; /************************************ Constructors ************************************/ // Numeral prototype object function Numeral(input, number) { this._input = input; this._value = number; } numeral = function(input) { var value, kind, unformatFunction, regexp; if (numeral.isNumeral(input)) { value = input.value(); } else if (input === 0 || typeof input === 'undefined') { value = 0; } else if (input === null || _.isNaN(input)) { value = null; } else if (typeof input === 'string') { if (options.zeroFormat && input === options.zeroFormat) { value = 0; } else if (options.nullFormat && input === options.nullFormat || !input.replace(/[^0-9]+/g, '').length) { value = null; } else { for (kind in formats) { regexp = typeof formats[kind].regexps.unformat === 'function' ? formats[kind].regexps.unformat() : formats[kind].regexps.unformat; if (regexp && input.match(regexp)) { unformatFunction = formats[kind].unformat; break; } } unformatFunction = unformatFunction || numeral._.stringToNumber; value = unformatFunction(input); } } else { value = Number(input)|| null; } return new Numeral(input, value); }; // version number numeral.version = VERSION; // compare numeral object numeral.isNumeral = function(obj) { return obj instanceof Numeral; }; // helper functions numeral._ = _ = { // formats numbers separators, decimals places, signs, abbreviations numberToFormat: function(value, format, roundingFunction) { var locale = locales[numeral.options.currentLocale], negP = false, optDec = false, leadingCount = 0, abbr = '', trillion = 1000000000000, billion = 1000000000, million = 1000000, thousand = 1000, decimal = '', neg = false, abbrForce, // force abbreviation abs, min, max, power, int, precision, signed, thousands, output; // make sure we never format a null value value = value || 0; abs = Math.abs(value); // see if we should use parentheses for negative number or if we should prefix with a sign // if both are present we default to parentheses if (numeral._.includes(format, '(')) { negP = true; format = format.replace(/[\(|\)]/g, ''); } else if (numeral._.includes(format, '+') || numeral._.includes(format, '-')) { signed = numeral._.includes(format, '+') ? format.indexOf('+') : value < 0 ? format.indexOf('-') : -1; format = format.replace(/[\+|\-]/g, ''); } // see if abbreviation is wanted if (numeral._.includes(format, 'a')) { abbrForce = format.match(/a(k|m|b|t)?/); abbrForce = abbrForce ? abbrForce[1] : false; // check for space before abbreviation if (numeral._.includes(format, ' a')) { abbr = ' '; } format = format.replace(new RegExp(abbr + 'a[kmbt]?'), ''); if (abs >= trillion && !abbrForce || abbrForce === 't') { // trillion abbr += locale.abbreviations.trillion; value = value / trillion; } else if (abs < trillion && abs >= billion && !abbrForce || abbrForce === 'b') { // billion abbr += locale.abbreviations.billion; value = value / billion; } else if (abs < billion && abs >= million && !abbrForce || abbrForce === 'm') { // million abbr += locale.abbreviations.million; value = value / million; } else if (abs < million && abs >= thousand && !abbrForce || abbrForce === 'k') { // thousand abbr += locale.abbreviations.thousand; value = value / thousand; } } // check for optional decimals if (numeral._.includes(format, '[.]')) { optDec = true; format = format.replace('[.]', '.'); } // break number and format int = value.toString().split('.')[0]; precision = format.split('.')[1]; thousands = format.indexOf(','); leadingCount = (format.split('.')[0].split(',')[0].match(/0/g) || []).length; if (precision) { if (numeral._.includes(precision, '[')) { precision = precision.replace(']', ''); precision = precision.split('['); decimal = numeral._.toFixed(value, (precision[0].length + precision[1].length), roundingFunction, precision[1].length); } else { decimal = numeral._.toFixed(value, precision.length, roundingFunction); } int = decimal.split('.')[0]; if (numeral._.includes(decimal, '.')) { decimal = locale.delimiters.decimal + decimal.split('.')[1]; } else { decimal = ''; } if (optDec && Number(decimal.slice(1)) === 0) { decimal = ''; } } else { int = numeral._.toFixed(value, 0, roundingFunction); } // check abbreviation again after rounding if (abbr && !abbrForce && Number(int) >= 1000 && abbr !== locale.abbreviations.trillion) { int = String(Number(int) / 1000); switch (abbr) { case locale.abbreviations.thousand: abbr = locale.abbreviations.million; break; case locale.abbreviations.million: abbr = locale.abbreviations.billion; break; case locale.abbreviations.billion: abbr = locale.abbreviations.trillion; break; } } // format number if (numeral._.includes(int, '-')) { int = int.slice(1); neg = true; } if (int.length < leadingCount) { for (var i = leadingCount - int.length; i > 0; i--) { int = '0' + int; } } if (thousands > -1) { int = int.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + locale.delimiters.thousands); } if (format.indexOf('.') === 0) { int = ''; } output = int + decimal + (abbr ? abbr : ''); if (negP) { output = (negP && neg ? '(' : '') + output + (negP && neg ? ')' : ''); } else { if (signed >= 0) { output = signed === 0 ? (neg ? '-' : '+') + output : output + (neg ? '-' : '+'); } else if (neg) { output = '-' + output; } } return output; }, // unformats numbers separators, decimals places, signs, abbreviations stringToNumber: function(string) { var locale = locales[options.currentLocale], stringOriginal = string, abbreviations = { thousand: 3, million: 6, billion: 9, trillion: 12 }, abbreviation, value, i, regexp; if (options.zeroFormat && string === options.zeroFormat) { value = 0; } else if (options.nullFormat && string === options.nullFormat || !string.replace(/[^0-9]+/g, '').length) { value = null; } else { value = 1; if (locale.delimiters.decimal !== '.') { string = string.replace(/\./g, '').replace(locale.delimiters.decimal, '.'); } for (abbreviation in abbreviations) { regexp = new RegExp('[^a-zA-Z]' + locale.abbreviations[abbreviation] + '(?:\\)|(\\' + locale.currency.symbol + ')?(?:\\))?)?$'); if (stringOriginal.match(regexp)) { value *= Math.pow(10, abbreviations[abbreviation]); break; } } // check for negative number value *= (string.split('-').length + Math.min(string.split('(').length - 1, string.split(')').length - 1)) % 2 ? 1 : -1; // remove non numbers string = string.replace(/[^0-9\.]+/g, ''); value *= Number(string); } return value; }, isNaN: function(value) { return typeof value === 'number' && isNaN(value); }, includes: function(string, search) { return string.indexOf(search) !== -1; }, insert: function(string, subString, start) { return string.slice(0, start) + subString + string.slice(start); }, reduce: function(array, callback /*, initialValue*/) { if (this === null) { throw new TypeError('Array.prototype.reduce called on null or undefined'); } if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } var t = Object(array), len = t.length >>> 0, k = 0, value; if (arguments.length === 3) { value = arguments[2]; } else { while (k < len && !(k in t)) { k++; } if (k >= len) { throw new TypeError('Reduce of empty array with no initial value'); } value = t[k++]; } for (; k < len; k++) { if (k in t) { value = callback(value, t[k], k, t); } } return value; }, /** * Computes the multiplier necessary to make x >= 1, * effectively eliminating miscalculations caused by * finite precision. */ multiplier: function (x) { var parts = x.toString().split('.'); return parts.length < 2 ? 1 : Math.pow(10, parts[1].length); }, /** * Given a variable number of arguments, returns the maximum * multiplier that must be used to normalize an operation involving * all of them. */ correctionFactor: function () { var args = Array.prototype.slice.call(arguments); return args.reduce(function(accum, next) { var mn = _.multiplier(next); return accum > mn ? accum : mn; }, 1); }, /** * Implementation of toFixed() that treats floats more like decimals * * Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present * problems for accounting- and finance-related software. */ toFixed: function(value, maxDecimals, roundingFunction, optionals) { var splitValue = value.toString().split('.'), minDecimals = maxDecimals - (optionals || 0), boundedPrecision, optionalsRegExp, power, output; // Use the smallest precision value possible to avoid errors from floating point representation if (splitValue.length === 2) { boundedPrecision = Math.min(Math.max(splitValue[1].length, minDecimals), maxDecimals); } else { boundedPrecision = minDecimals; } power = Math.pow(10, boundedPrecision); // Multiply up by precision, round accurately, then divide and use native toFixed(): output = (roundingFunction(value + 'e+' + boundedPrecision) / power).toFixed(boundedPrecision); if (optionals > maxDecimals - boundedPrecision) { optionalsRegExp = new RegExp('\\.?0{1,' + (optionals - (maxDecimals - boundedPrecision)) + '}$'); output = output.replace(optionalsRegExp, ''); } return output; } }; // avaliable options numeral.options = options; // avaliable formats numeral.formats = formats; // avaliable formats numeral.locales = locales; // This function sets the current locale. If // no arguments are passed in, it will simply return the current global // locale key. numeral.locale = function(key) { if (key) { options.currentLocale = key.toLowerCase(); } return options.currentLocale; }; // This function provides access to the loaded locale data. If // no arguments are passed in, it will simply return the current // global locale object. numeral.localeData = function(key) { if (!key) { return locales[options.currentLocale]; } key = key.toLowerCase(); if (!locales[key]) { throw new Error('Unknown locale : ' + key); } return locales[key]; }; numeral.reset = function() { for (var property in defaults) { options[property] = defaults[property]; } }; numeral.zeroFormat = function(format) { options.zeroFormat = typeof(format) === 'string' ? format : null; }; numeral.nullFormat = function (format) { options.nullFormat = typeof(format) === 'string' ? format : null; }; numeral.defaultFormat = function(format) { options.defaultFormat = typeof(format) === 'string' ? format : '0.0'; }; numeral.register = function(type, name, format) { name = name.toLowerCase(); if (this[type + 's'][name]) { throw new TypeError(name + ' ' + type + ' already registered.'); } this[type + 's'][name] = format; return format; }; numeral.validate = function(val, culture) { var _decimalSep, _thousandSep, _currSymbol, _valArray, _abbrObj, _thousandRegEx, localeData, temp; //coerce val to string if (typeof val !== 'string') { val += ''; if (console.warn) { console.warn('Numeral.js: Value is not string. It has been co-erced to: ', val); } } //trim whitespaces from either sides val = val.trim(); //if val is just digits return true if (!!val.match(/^\d+$/)) { return true; } //if val is empty return false if (val === '') { return false; } //get the decimal and thousands separator from numeral.localeData try { //check if the culture is understood by numeral. if not, default it to current locale localeData = numeral.localeData(culture); } catch (e) { localeData = numeral.localeData(numeral.locale()); } //setup the delimiters and currency symbol based on culture/locale _currSymbol = localeData.currency.symbol; _abbrObj = localeData.abbreviations; _decimalSep = localeData.delimiters.decimal; if (localeData.delimiters.thousands === '.') { _thousandSep = '\\.'; } else { _thousandSep = localeData.delimiters.thousands; } // validating currency symbol temp = val.match(/^[^\d]+/); if (temp !== null) { val = val.substr(1); if (temp[0] !== _currSymbol) { return false; } } //validating abbreviation symbol temp = val.match(/[^\d]+$/); if (temp !== null) { val = val.slice(0, -1); if (temp[0] !== _abbrObj.thousand && temp[0] !== _abbrObj.million && temp[0] !== _abbrObj.billion && temp[0] !== _abbrObj.trillion) { return false; } } _thousandRegEx = new RegExp(_thousandSep + '{2}'); if (!val.match(/[^\d.,]/g)) { _valArray = val.split(_decimalSep); if (_valArray.length > 2) { return false; } else { if (_valArray.length < 2) { return ( !! _valArray[0].match(/^\d+.*\d$/) && !_valArray[0].match(_thousandRegEx)); } else { if (_valArray[0].length === 1) { return ( !! _valArray[0].match(/^\d+$/) && !_valArray[0].match(_thousandRegEx) && !! _valArray[1].match(/^\d+$/)); } else { return ( !! _valArray[0].match(/^\d+.*\d$/) && !_valArray[0].match(_thousandRegEx) && !! _valArray[1].match(/^\d+$/)); } } } } return false; }; /************************************ Numeral Prototype ************************************/ numeral.fn = Numeral.prototype = { clone: function() { return numeral(this); }, format: function(inputString, roundingFunction) { var value = this._value, format = inputString || options.defaultFormat, kind, output, formatFunction; // make sure we have a roundingFunction roundingFunction = roundingFunction || Math.round; // format based on value if (value === 0 && options.zeroFormat !== null) { output = options.zeroFormat; } else if (value === null && options.nullFormat !== null) { output = options.nullFormat; } else { for (kind in formats) { if (format.match(formats[kind].regexps.format)) { formatFunction = formats[kind].format; break; } } formatFunction = formatFunction || numeral._.numberToFormat; output = formatFunction(value, format, roundingFunction); } return output; }, value: function() { return this._value; }, input: function() { return this._input; }, set: function(value) { this._value = Number(value); return this; }, add: function(value) { var corrFactor = _.correctionFactor.call(null, this._value, value); function cback(accum, curr, currI, O) { return accum + Math.round(corrFactor * curr); } this._value = _.reduce([this._value, value], cback, 0) / corrFactor; return this; }, subtract: function(value) { var corrFactor = _.correctionFactor.call(null, this._value, value); function cback(accum, curr, currI, O) { return accum - Math.round(corrFactor * curr); } this._value = _.reduce([value], cback, Math.round(this._value * corrFactor)) / corrFactor; return this; }, multiply: function(value) { function cback(accum, curr, currI, O) { var corrFactor = _.correctionFactor(accum, curr); return Math.round(accum * corrFactor) * Math.round(curr * corrFactor) / Math.round(corrFactor * corrFactor); } this._value = _.reduce([this._value, value], cback, 1); return this; }, divide: function(value) { function cback(accum, curr, currI, O) { var corrFactor = _.correctionFactor(accum, curr); return Math.round(accum * corrFactor) / Math.round(curr * corrFactor); } this._value = _.reduce([this._value, value], cback); return this; }, difference: function(value) { return Math.abs(numeral(this._value).subtract(value).value()); } }; /************************************ Default Locale && Format ************************************/ numeral.register('locale', 'en', { delimiters: { thousands: ',', decimal: '.' }, abbreviations: { thousand: 'k', million: 'm', billion: 'b', trillion: 't' }, ordinal: function(number) { var b = number % 10; return (~~(number % 100 / 10) === 1) ? 'th' : (b === 1) ? 'st' : (b === 2) ? 'nd' : (b === 3) ? 'rd' : 'th'; }, currency: { symbol: '$' } }); (function() { numeral.register('format', 'bps', { regexps: { format: /(BPS)/, unformat: /(BPS)/ }, format: function(value, format, roundingFunction) { var space = numeral._.includes(format, ' BPS') ? ' ' : '', output; value = value * 10000; // check for space before BPS format = format.replace(/\s?BPS/, ''); output = numeral._.numberToFormat(value, format, roundingFunction); if (numeral._.includes(output, ')')) { output = output.split(''); output.splice(-1, 0, space + 'BPS'); output = output.join(''); } else { output = output + space + 'BPS'; } return output; }, unformat: function(string) { return +(numeral._.stringToNumber(string) * 0.0001).toFixed(15); } }); })(); (function() { var decimal = { base: 1000, suffixes: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] }, binary = { base: 1024, suffixes: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] }; var allSuffixes = decimal.suffixes.concat(binary.suffixes.filter(function (item) { return decimal.suffixes.indexOf(item) < 0; })); var unformatRegex = allSuffixes.join('|'); // Allow support for BPS (http://www.investopedia.com/terms/b/basispoint.asp) unformatRegex = '(' + unformatRegex.replace('B', 'B(?!PS)') + ')'; numeral.register('format', 'bytes', { regexps: { format: /([0\s]i?b)/, unformat: new RegExp(unformatRegex) }, format: function(value, format, roundingFunction) { var output, bytes = numeral._.includes(format, 'ib') ? binary : decimal, suffix = numeral._.includes(format, ' b') || numeral._.includes(format, ' ib') ? ' ' : '', power, min, max; // check for space before format = format.replace(/\s?i?b/, ''); for (power = 0; power <= bytes.suffixes.length; power++) { min = Math.pow(bytes.base, power); max = Math.pow(bytes.base, power + 1); if (value === null || value === 0 || value >= min && value < max) { suffix += bytes.suffixes[power]; if (min > 0) { value = value / min; } break; } } output = numeral._.numberToFormat(value, format, roundingFunction); return output + suffix; }, unformat: function(string) { var value = numeral._.stringToNumber(string), power, bytesMultiplier; if (value) { for (power = decimal.suffixes.length - 1; power >= 0; power--) { if (numeral._.includes(string, decimal.suffixes[power])) { bytesMultiplier = Math.pow(decimal.base, power); break; } if (numeral._.includes(string, binary.suffixes[power])) { bytesMultiplier = Math.pow(binary.base, power); break; } } value *= (bytesMultiplier || 1); } return value; } }); })(); (function() { numeral.register('format', 'currency', { regexps: { format: /(\$)/ }, format: function(value, format, roundingFunction) { var locale = numeral.locales[numeral.options.currentLocale], symbols = { before: format.match(/^([\+|\-|\(|\s|\$]*)/)[0], after: format.match(/([\+|\-|\)|\s|\$]*)$/)[0] }, output, symbol, i; // strip format of spaces and $ format = format.replace(/\s?\$\s?/, ''); // format the number output = numeral._.numberToFormat(value, format, roundingFunction); // update the before and after based on value if (value >= 0) { symbols.before = symbols.before.replace(/[\-\(]/, ''); symbols.after = symbols.after.replace(/[\-\)]/, ''); } else if (value < 0 && (!numeral._.includes(symbols.before, '-') && !numeral._.includes(symbols.before, '('))) { symbols.before = '-' + symbols.before; } // loop through each before symbol for (i = 0; i < symbols.before.length; i++) { symbol = symbols.before[i]; switch (symbol) { case '$': output = numeral._.insert(output, locale.currency.symbol, i); break; case ' ': output = numeral._.insert(output, ' ', i + locale.currency.symbol.length - 1); break; } } // loop through each after symbol for (i = symbols.after.length - 1; i >= 0; i--) { symbol = symbols.after[i]; switch (symbol) { case '$': output = i === symbols.after.length - 1 ? output + locale.currency.symbol : numeral._.insert(output, locale.currency.symbol, -(symbols.after.length - (1 + i))); break; case ' ': output = i === symbols.after.length - 1 ? output + ' ' : numeral._.insert(output, ' ', -(symbols.after.length - (1 + i) + locale.currency.symbol.length - 1)); break; } } return output; } }); })(); (function() { numeral.register('format', 'exponential', { regexps: { format: /(e\+|e-)/, unformat: /(e\+|e-)/ }, format: function(value, format, roundingFunction) { var output, exponential = typeof value === 'number' && !numeral._.isNaN(value) ? value.toExponential() : '0e+0', parts = exponential.split('e'); format = format.replace(/e[\+|\-]{1}0/, ''); output = numeral._.numberToFormat(Number(parts[0]), format, roundingFunction); return output + 'e' + parts[1]; }, unformat: function(string) { var parts = numeral._.includes(string, 'e+') ? string.split('e+') : string.split('e-'), value = Number(parts[0]), power = Number(parts[1]); power = numeral._.includes(string, 'e-') ? power *= -1 : power; function cback(accum, curr, currI, O) { var corrFactor = numeral._.correctionFactor(accum, curr), num = (accum * corrFactor) * (curr * corrFactor) / (corrFactor * corrFactor); return num; } return numeral._.reduce([value, Math.pow(10, power)], cback, 1); } }); })(); (function() { numeral.register('format', 'ordinal', { regexps: { format: /(o)/ }, format: function(value, format, roundingFunction) { var locale = numeral.locales[numeral.options.currentLocale], output, ordinal = numeral._.includes(format, ' o') ? ' ' : ''; // check for space before format = format.replace(/\s?o/, ''); ordinal += locale.ordinal(value); output = numeral._.numberToFormat(value, format, roundingFunction); return output + ordinal; } }); })(); (function() { numeral.register('format', 'percentage', { regexps: { format: /(%)/, unformat: /(%)/ }, format: function(value, format, roundingFunction) { var space = numeral._.includes(format, ' %') ? ' ' : '', output; if (numeral.options.scalePercentBy100) { value = value * 100; } // check for space before % format = format.replace(/\s?\%/, ''); output = numeral._.numberToFormat(value, format, roundingFunction); if (numeral._.includes(output, ')')) { output = output.split(''); output.splice(-1, 0, space + '%'); output = output.join(''); } else { output = output + space + '%'; } return output; }, unformat: function(string) { var number = numeral._.stringToNumber(string); if (numeral.options.scalePercentBy100) { return number * 0.01; } return number; } }); })(); (function() { numeral.register('format', 'time', { regexps: { format: /(:)/, unformat: /(:)/ }, format: function(value, format, roundingFunction) { var hours = Math.floor(value / 60 / 60), minutes = Math.floor((value - (hours * 60 * 60)) / 60), seconds = Math.round(value - (hours * 60 * 60) - (minutes * 60)); return hours + ':' + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds); }, unformat: function(string) { var timeArray = string.split(':'), seconds = 0; // turn hours and minutes into seconds and add them all up if (timeArray.length === 3) { // hours seconds = seconds + (Number(timeArray[0]) * 60 * 60); // minutes seconds = seconds + (Number(timeArray[1]) * 60); // seconds seconds = seconds + Number(timeArray[2]); } else if (timeArray.length === 2) { // minutes seconds = seconds + (Number(timeArray[0]) * 60); // seconds seconds = seconds + Number(timeArray[1]); } return Number(seconds); } }); })(); return numeral; })); },{}],5:[function(require,module,exports){ (function (global){ /**! * @fileOverview Kickass library to create and place poppers near their reference elements. * @version 1.16.0 * @license * Copyright (c) 2016 Federico Zivolo and contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.Popper = factory()); }(this, (function () { 'use strict'; var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined'; var timeoutDuration = function () { var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { return 1; } } return 0; }(); function microtaskDebounce(fn) { var called = false; return function () { if (called) { return; } called = true; window.Promise.resolve().then(function () { called = false; fn(); }); }; } function taskDebounce(fn) { var scheduled = false; return function () { if (!scheduled) { scheduled = true; setTimeout(function () { scheduled = false; fn(); }, timeoutDuration); } }; } var supportsMicroTasks = isBrowser && window.Promise; /** * Create a debounced version of a method, that's asynchronously deferred * but called in the minimum time possible. * * @method * @memberof Popper.Utils * @argument {Function} fn * @returns {Function} */ var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; /** * Check if the given variable is a function * @method * @memberof Popper.Utils * @argument {Any} functionToCheck - variable to check * @returns {Boolean} answer to: is a function? */ function isFunction(functionToCheck) { var getType = {}; return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; } /** * Get CSS computed property of the given element * @method * @memberof Popper.Utils * @argument {Eement} element * @argument {String} property */ function getStyleComputedProperty(element, property) { if (element.nodeType !== 1) { return []; } // NOTE: 1 DOM access here var window = element.ownerDocument.defaultView; var css = window.getComputedStyle(element, null); return property ? css[property] : css; } /** * Returns the parentNode or the host of the element * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Element} parent */ function getParentNode(element) { if (element.nodeName === 'HTML') { return element; } return element.parentNode || element.host; } /** * Returns the scrolling parent of the given element * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Element} scroll parent */ function getScrollParent(element) { // Return body, `getScroll` will take care to get the correct `scrollTop` from it if (!element) { return document.body; } switch (element.nodeName) { case 'HTML': case 'BODY': return element.ownerDocument.body; case '#document': return element.body; } // Firefox want us to check `-x` and `-y` variations as well var _getStyleComputedProp = getStyleComputedProperty(element), overflow = _getStyleComputedProp.overflow, overflowX = _getStyleComputedProp.overflowX, overflowY = _getStyleComputedProp.overflowY; if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { return element; } return getScrollParent(getParentNode(element)); } /** * Returns the reference node of the reference object, or the reference object itself. * @method * @memberof Popper.Utils * @param {Element|Object} reference - the reference element (the popper will be relative to this) * @returns {Element} parent */ function getReferenceNode(reference) { return reference && reference.referenceNode ? reference.referenceNode : reference; } var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); /** * Determines if the browser is Internet Explorer * @method * @memberof Popper.Utils * @param {Number} version to check * @returns {Boolean} isIE */ function isIE(version) { if (version === 11) { return isIE11; } if (version === 10) { return isIE10; } return isIE11 || isIE10; } /** * Returns the offset parent of the given element * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Element} offset parent */ function getOffsetParent(element) { if (!element) { return document.documentElement; } var noOffsetParent = isIE(10) ? document.body : null; // NOTE: 1 DOM access here var offsetParent = element.offsetParent || null; // Skip hidden elements which don't have an offsetParent while (offsetParent === noOffsetParent && element.nextElementSibling) { offsetParent = (element = element.nextElementSibling).offsetParent; } var nodeName = offsetParent && offsetParent.nodeName; if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { return element ? element.ownerDocument.documentElement : document.documentElement; } // .offsetParent will return the closest TH, TD or TABLE in case // no offsetParent is present, I hate this job... if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { return getOffsetParent(offsetParent); } return offsetParent; } function isOffsetContainer(element) { var nodeName = element.nodeName; if (nodeName === 'BODY') { return false; } return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; } /** * Finds the root node (document, shadowDOM root) of the given element * @method * @memberof Popper.Utils * @argument {Element} node * @returns {Element} root node */ function getRoot(node) { if (node.parentNode !== null) { return getRoot(node.parentNode); } return node; } /** * Finds the offset parent common to the two provided nodes * @method * @memberof Popper.Utils * @argument {Element} element1 * @argument {Element} element2 * @returns {Element} common offset parent */ function findCommonOffsetParent(element1, element2) { // This check is needed to avoid errors in case one of the elements isn't defined for any reason if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { return document.documentElement; } // Here we make sure to give as "start" the element that comes first in the DOM var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; var start = order ? element1 : element2; var end = order ? element2 : element1; // Get common ancestor container var range = document.createRange(); range.setStart(start, 0); range.setEnd(end, 0); var commonAncestorContainer = range.commonAncestorContainer; // Both nodes are inside #document if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { if (isOffsetContainer(commonAncestorContainer)) { return commonAncestorContainer; } return getOffsetParent(commonAncestorContainer); } // one of the nodes is inside shadowDOM, find which one var element1root = getRoot(element1); if (element1root.host) { return findCommonOffsetParent(element1root.host, element2); } else { return findCommonOffsetParent(element1, getRoot(element2).host); } } /** * Gets the scroll value of the given element in the given side (top and left) * @method * @memberof Popper.Utils * @argument {Element} element * @argument {String} side `top` or `left` * @returns {number} amount of scrolled pixels */ function getScroll(element) { var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; var nodeName = element.nodeName; if (nodeName === 'BODY' || nodeName === 'HTML') { var html = element.ownerDocument.documentElement; var scrollingElement = element.ownerDocument.scrollingElement || html; return scrollingElement[upperSide]; } return element[upperSide]; } /* * Sum or subtract the element scroll values (left and top) from a given rect object * @method * @memberof Popper.Utils * @param {Object} rect - Rect object you want to change * @param {HTMLElement} element - The element from the function reads the scroll values * @param {Boolean} subtract - set to true if you want to subtract the scroll values * @return {Object} rect - The modifier rect object */ function includeScroll(rect, element) { var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var scrollTop = getScroll(element, 'top'); var scrollLeft = getScroll(element, 'left'); var modifier = subtract ? -1 : 1; rect.top += scrollTop * modifier; rect.bottom += scrollTop * modifier; rect.left += scrollLeft * modifier; rect.right += scrollLeft * modifier; return rect; } /* * Helper to detect borders of a given element * @method * @memberof Popper.Utils * @param {CSSStyleDeclaration} styles * Result of `getStyleComputedProperty` on the given element * @param {String} axis - `x` or `y` * @return {number} borders - The borders size of the given axis */ function getBordersSize(styles, axis) { var sideA = axis === 'x' ? 'Left' : 'Top'; var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10); } function getSize(axis, body, html, computedStyle) { return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0); } function getWindowSizes(document) { var body = document.body; var html = document.documentElement; var computedStyle = isIE(10) && getComputedStyle(html); return { height: getSize('Height', body, html, computedStyle), width: getSize('Width', body, html, computedStyle) }; } var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var defineProperty = function (obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /** * Given element offsets, generate an output similar to getBoundingClientRect * @method * @memberof Popper.Utils * @argument {Object} offsets * @returns {Object} ClientRect like output */ function getClientRect(offsets) { return _extends({}, offsets, { right: offsets.left + offsets.width, bottom: offsets.top + offsets.height }); } /** * Get bounding client rect of given element * @method * @memberof Popper.Utils * @param {HTMLElement} element * @return {Object} client rect */ function getBoundingClientRect(element) { var rect = {}; // IE10 10 FIX: Please, don't ask, the element isn't // considered in DOM in some circumstances... // This isn't reproducible in IE10 compatibility mode of IE11 try { if (isIE(10)) { rect = element.getBoundingClientRect(); var scrollTop = getScroll(element, 'top'); var scrollLeft = getScroll(element, 'left'); rect.top += scrollTop; rect.left += scrollLeft; rect.bottom += scrollTop; rect.right += scrollLeft; } else { rect = element.getBoundingClientRect(); } } catch (e) {} var result = { left: rect.left, top: rect.top, width: rect.right - rect.left, height: rect.bottom - rect.top }; // subtract scrollbar size from sizes var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; var width = sizes.width || element.clientWidth || result.width; var height = sizes.height || element.clientHeight || result.height; var horizScrollbar = element.offsetWidth - width; var vertScrollbar = element.offsetHeight - height; // if an hypothetical scrollbar is detected, we must be sure it's not a `border` // we make this check conditional for performance reasons if (horizScrollbar || vertScrollbar) { var styles = getStyleComputedProperty(element); horizScrollbar -= getBordersSize(styles, 'x'); vertScrollbar -= getBordersSize(styles, 'y'); result.width -= horizScrollbar; result.height -= vertScrollbar; } return getClientRect(result); } function getOffsetRectRelativeToArbitraryNode(children, parent) { var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var isIE10 = isIE(10); var isHTML = parent.nodeName === 'HTML'; var childrenRect = getBoundingClientRect(children); var parentRect = getBoundingClientRect(parent); var scrollParent = getScrollParent(children); var styles = getStyleComputedProperty(parent); var borderTopWidth = parseFloat(styles.borderTopWidth, 10); var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10); // In cases where the parent is fixed, we must ignore negative scroll in offset calc if (fixedPosition && isHTML) { parentRect.top = Math.max(parentRect.top, 0); parentRect.left = Math.max(parentRect.left, 0); } var offsets = getClientRect({ top: childrenRect.top - parentRect.top - borderTopWidth, left: childrenRect.left - parentRect.left - borderLeftWidth, width: childrenRect.width, height: childrenRect.height }); offsets.marginTop = 0; offsets.marginLeft = 0; // Subtract margins of documentElement in case it's being used as parent // we do this only on HTML because it's the only element that behaves // differently when margins are applied to it. The margins are included in // the box of the documentElement, in the other cases not. if (!isIE10 && isHTML) { var marginTop = parseFloat(styles.marginTop, 10); var marginLeft = parseFloat(styles.marginLeft, 10); offsets.top -= borderTopWidth - marginTop; offsets.bottom -= borderTopWidth - marginTop; offsets.left -= borderLeftWidth - marginLeft; offsets.right -= borderLeftWidth - marginLeft; // Attach marginTop and marginLeft because in some circumstances we may need them offsets.marginTop = marginTop; offsets.marginLeft = marginLeft; } if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { offsets = includeScroll(offsets, parent); } return offsets; } function getViewportOffsetRectRelativeToArtbitraryNode(element) { var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var html = element.ownerDocument.documentElement; var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); var width = Math.max(html.clientWidth, window.innerWidth || 0); var height = Math.max(html.clientHeight, window.innerHeight || 0); var scrollTop = !excludeScroll ? getScroll(html) : 0; var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; var offset = { top: scrollTop - relativeOffset.top + relativeOffset.marginTop, left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, width: width, height: height }; return getClientRect(offset); } /** * Check if the given element is fixed or is inside a fixed parent * @method * @memberof Popper.Utils * @argument {Element} element * @argument {Element} customContainer * @returns {Boolean} answer to "isFixed?" */ function isFixed(element) { var nodeName = element.nodeName; if (nodeName === 'BODY' || nodeName === 'HTML') { return false; } if (getStyleComputedProperty(element, 'position') === 'fixed') { return true; } var parentNode = getParentNode(element); if (!parentNode) { return false; } return isFixed(parentNode); } /** * Finds the first parent of an element that has a transformed property defined * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Element} first transformed parent or documentElement */ function getFixedPositionOffsetParent(element) { // This check is needed to avoid errors in case one of the elements isn't defined for any reason if (!element || !element.parentElement || isIE()) { return document.documentElement; } var el = element.parentElement; while (el && getStyleComputedProperty(el, 'transform') === 'none') { el = el.parentElement; } return el || document.documentElement; } /** * Computed the boundaries limits and return them * @method * @memberof Popper.Utils * @param {HTMLElement} popper * @param {HTMLElement} reference * @param {number} padding * @param {HTMLElement} boundariesElement - Element used to define the boundaries * @param {Boolean} fixedPosition - Is in fixed position mode * @returns {Object} Coordinates of the boundaries */ function getBoundaries(popper, reference, padding, boundariesElement) { var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; // NOTE: 1 DOM access here var boundaries = { top: 0, left: 0 }; var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); // Handle viewport case if (boundariesElement === 'viewport') { boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); } else { // Handle other cases based on DOM element used as boundaries var boundariesNode = void 0; if (boundariesElement === 'scrollParent') { boundariesNode = getScrollParent(getParentNode(reference)); if (boundariesNode.nodeName === 'BODY') { boundariesNode = popper.ownerDocument.documentElement; } } else if (boundariesElement === 'window') { boundariesNode = popper.ownerDocument.documentElement; } else { boundariesNode = boundariesElement; } var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); // In case of HTML, we need a different computation if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { var _getWindowSizes = getWindowSizes(popper.ownerDocument), height = _getWindowSizes.height, width = _getWindowSizes.width; boundaries.top += offsets.top - offsets.marginTop; boundaries.bottom = height + offsets.top; boundaries.left += offsets.left - offsets.marginLeft; boundaries.right = width + offsets.left; } else { // for all the other DOM elements, this one is good boundaries = offsets; } } // Add paddings padding = padding || 0; var isPaddingNumber = typeof padding === 'number'; boundaries.left += isPaddingNumber ? padding : padding.left || 0; boundaries.top += isPaddingNumber ? padding : padding.top || 0; boundaries.right -= isPaddingNumber ? padding : padding.right || 0; boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; return boundaries; } function getArea(_ref) { var width = _ref.width, height = _ref.height; return width * height; } /** * Utility used to transform the `auto` placement to the placement with more * available space. * @method * @memberof Popper.Utils * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; if (placement.indexOf('auto') === -1) { return placement; } var boundaries = getBoundaries(popper, reference, padding, boundariesElement); var rects = { top: { width: boundaries.width, height: refRect.top - boundaries.top }, right: { width: boundaries.right - refRect.right, height: boundaries.height }, bottom: { width: boundaries.width, height: boundaries.bottom - refRect.bottom }, left: { width: refRect.left - boundaries.left, height: boundaries.height } }; var sortedAreas = Object.keys(rects).map(function (key) { return _extends({ key: key }, rects[key], { area: getArea(rects[key]) }); }).sort(function (a, b) { return b.area - a.area; }); var filteredAreas = sortedAreas.filter(function (_ref2) { var width = _ref2.width, height = _ref2.height; return width >= popper.clientWidth && height >= popper.clientHeight; }); var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; var variation = placement.split('-')[1]; return computedPlacement + (variation ? '-' + variation : ''); } /** * Get offsets to the reference element * @method * @memberof Popper.Utils * @param {Object} state * @param {Element} popper - the popper element * @param {Element} reference - the reference element (the popper will be relative to this) * @param {Element} fixedPosition - is in fixed position mode * @returns {Object} An object containing the offsets which will be applied to the popper */ function getReferenceOffsets(state, popper, reference) { var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); } /** * Get the outer sizes of the given element (offset size + margins) * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Object} object containing width and height properties */ function getOuterSizes(element) { var window = element.ownerDocument.defaultView; var styles = window.getComputedStyle(element); var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0); var result = { width: element.offsetWidth + y, height: element.offsetHeight + x }; return result; } /** * Get the opposite placement of the given one * @method * @memberof Popper.Utils * @argument {String} placement * @returns {String} flipped placement */ function getOppositePlacement(placement) { var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; return placement.replace(/left|right|bottom|top/g, function (matched) { return hash[matched]; }); } /** * Get offsets to the popper * @method * @memberof Popper.Utils * @param {Object} position - CSS position the Popper will get applied * @param {HTMLElement} popper - the popper element * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) * @param {String} placement - one of the valid placement options * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper */ function getPopperOffsets(popper, referenceOffsets, placement) { placement = placement.split('-')[0]; // Get popper node sizes var popperRect = getOuterSizes(popper); // Add position, width and height to our offsets object var popperOffsets = { width: popperRect.width, height: popperRect.height }; // depending by the popper placement we have to compute its offsets slightly differently var isHoriz = ['right', 'left'].indexOf(placement) !== -1; var mainSide = isHoriz ? 'top' : 'left'; var secondarySide = isHoriz ? 'left' : 'top'; var measurement = isHoriz ? 'height' : 'width'; var secondaryMeasurement = !isHoriz ? 'height' : 'width'; popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; if (placement === secondarySide) { popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; } else { popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; } return popperOffsets; } /** * Mimics the `find` method of Array * @method * @memberof Popper.Utils * @argument {Array} arr * @argument prop * @argument value * @returns index or -1 */ function find(arr, check) { // use native find if supported if (Array.prototype.find) { return arr.find(check); } // use `filter` to obtain the same behavior of `find` return arr.filter(check)[0]; } /** * Return the index of the matching object * @method * @memberof Popper.Utils * @argument {Array} arr * @argument prop * @argument value * @returns index or -1 */ function findIndex(arr, prop, value) { // use native findIndex if supported if (Array.prototype.findIndex) { return arr.findIndex(function (cur) { return cur[prop] === value; }); } // use `find` + `indexOf` if `findIndex` isn't supported var match = find(arr, function (obj) { return obj[prop] === value; }); return arr.indexOf(match); } /** * Loop trough the list of modifiers and run them in order, * each of them will then edit the data object. * @method * @memberof Popper.Utils * @param {dataObject} data * @param {Array} modifiers * @param {String} ends - Optional modifier name used as stopper * @returns {dataObject} */ function runModifiers(modifiers, data, ends) { var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); modifiersToRun.forEach(function (modifier) { if (modifier['function']) { // eslint-disable-line dot-notation console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); } var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation if (modifier.enabled && isFunction(fn)) { // Add properties to offsets to make them a complete clientRect object // we do this before each modifier to make sure the previous one doesn't // mess with these values data.offsets.popper = getClientRect(data.offsets.popper); data.offsets.reference = getClientRect(data.offsets.reference); data = fn(data, modifier); } }); return data; } /** * Updates the position of the popper, computing the new offsets and applying * the new style.
* Prefer `scheduleUpdate` over `update` because of performance reasons. * @method * @memberof Popper */ function update() { // if popper is destroyed, don't perform any further update if (this.state.isDestroyed) { return; } var data = { instance: this, styles: {}, arrowStyles: {}, attributes: {}, flipped: false, offsets: {} }; // compute reference element offsets data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); // compute auto placement, store placement inside the data object, // modifiers will be able to edit `placement` if needed // and refer to originalPlacement to know the original value data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); // store the computed placement inside `originalPlacement` data.originalPlacement = data.placement; data.positionFixed = this.options.positionFixed; // compute the popper offsets data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; // run the modifiers data = runModifiers(this.modifiers, data); // the first `update` will call `onCreate` callback // the other ones will call `onUpdate` callback if (!this.state.isCreated) { this.state.isCreated = true; this.options.onCreate(data); } else { this.options.onUpdate(data); } } /** * Helper used to know if the given modifier is enabled. * @method * @memberof Popper.Utils * @returns {Boolean} */ function isModifierEnabled(modifiers, modifierName) { return modifiers.some(function (_ref) { var name = _ref.name, enabled = _ref.enabled; return enabled && name === modifierName; }); } /** * Get the prefixed supported property name * @method * @memberof Popper.Utils * @argument {String} property (camelCase) * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) */ function getSupportedPropertyName(property) { var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; var upperProp = property.charAt(0).toUpperCase() + property.slice(1); for (var i = 0; i < prefixes.length; i++) { var prefix = prefixes[i]; var toCheck = prefix ? '' + prefix + upperProp : property; if (typeof document.body.style[toCheck] !== 'undefined') { return toCheck; } } return null; } /** * Destroys the popper. * @method * @memberof Popper */ function destroy() { this.state.isDestroyed = true; // touch DOM only if `applyStyle` modifier is enabled if (isModifierEnabled(this.modifiers, 'applyStyle')) { this.popper.removeAttribute('x-placement'); this.popper.style.position = ''; this.popper.style.top = ''; this.popper.style.left = ''; this.popper.style.right = ''; this.popper.style.bottom = ''; this.popper.style.willChange = ''; this.popper.style[getSupportedPropertyName('transform')] = ''; } this.disableEventListeners(); // remove the popper if user explicitly asked for the deletion on destroy // do not use `remove` because IE11 doesn't support it if (this.options.removeOnDestroy) { this.popper.parentNode.removeChild(this.popper); } return this; } /** * Get the window associated with the element * @argument {Element} element * @returns {Window} */ function getWindow(element) { var ownerDocument = element.ownerDocument; return ownerDocument ? ownerDocument.defaultView : window; } function attachToScrollParents(scrollParent, event, callback, scrollParents) { var isBody = scrollParent.nodeName === 'BODY'; var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; target.addEventListener(event, callback, { passive: true }); if (!isBody) { attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); } scrollParents.push(target); } /** * Setup needed event listeners used to update the popper position * @method * @memberof Popper.Utils * @private */ function setupEventListeners(reference, options, state, updateBound) { // Resize event listener on window state.updateBound = updateBound; getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); // Scroll event listener on scroll parents var scrollElement = getScrollParent(reference); attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); state.scrollElement = scrollElement; state.eventsEnabled = true; return state; } /** * It will add resize/scroll events and start recalculating * position of the popper element when they are triggered. * @method * @memberof Popper */ function enableEventListeners() { if (!this.state.eventsEnabled) { this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); } } /** * Remove event listeners used to update the popper position * @method * @memberof Popper.Utils * @private */ function removeEventListeners(reference, state) { // Remove resize event listener on window getWindow(reference).removeEventListener('resize', state.updateBound); // Remove scroll event listener on scroll parents state.scrollParents.forEach(function (target) { target.removeEventListener('scroll', state.updateBound); }); // Reset state state.updateBound = null; state.scrollParents = []; state.scrollElement = null; state.eventsEnabled = false; return state; } /** * It will remove resize/scroll events and won't recalculate popper position * when they are triggered. It also won't trigger `onUpdate` callback anymore, * unless you call `update` method manually. * @method * @memberof Popper */ function disableEventListeners() { if (this.state.eventsEnabled) { cancelAnimationFrame(this.scheduleUpdate); this.state = removeEventListeners(this.reference, this.state); } } /** * Tells if a given input is a number * @method * @memberof Popper.Utils * @param {*} input to check * @return {Boolean} */ function isNumeric(n) { return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); } /** * Set the style to the given popper * @method * @memberof Popper.Utils * @argument {Element} element - Element to apply the style to * @argument {Object} styles * Object with a list of properties and values which will be applied to the element */ function setStyles(element, styles) { Object.keys(styles).forEach(function (prop) { var unit = ''; // add unit if the value is numeric and is one of the following if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { unit = 'px'; } element.style[prop] = styles[prop] + unit; }); } /** * Set the attributes to the given popper * @method * @memberof Popper.Utils * @argument {Element} element - Element to apply the attributes to * @argument {Object} styles * Object with a list of properties and values which will be applied to the element */ function setAttributes(element, attributes) { Object.keys(attributes).forEach(function (prop) { var value = attributes[prop]; if (value !== false) { element.setAttribute(prop, attributes[prop]); } else { element.removeAttribute(prop); } }); } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} data.styles - List of style properties - values to apply to popper element * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element * @argument {Object} options - Modifiers configuration and options * @returns {Object} The same data object */ function applyStyle(data) { // any property present in `data.styles` will be applied to the popper, // in this way we can make the 3rd party modifiers add custom styles to it // Be aware, modifiers could override the properties defined in the previous // lines of this modifier! setStyles(data.instance.popper, data.styles); // any property present in `data.attributes` will be applied to the popper, // they will be set as HTML attributes of the element setAttributes(data.instance.popper, data.attributes); // if arrowElement is defined and arrowStyles has some properties if (data.arrowElement && Object.keys(data.arrowStyles).length) { setStyles(data.arrowElement, data.arrowStyles); } return data; } /** * Set the x-placement attribute before everything else because it could be used * to add margins to the popper margins needs to be calculated to get the * correct popper offsets. * @method * @memberof Popper.modifiers * @param {HTMLElement} reference - The reference element used to position the popper * @param {HTMLElement} popper - The HTML element used as popper * @param {Object} options - Popper.js options */ function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { // compute reference element offsets var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); // compute auto placement, store placement inside the data object, // modifiers will be able to edit `placement` if needed // and refer to originalPlacement to know the original value var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); popper.setAttribute('x-placement', placement); // Apply `position` to popper before anything else because // without the position applied we can't guarantee correct computations setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); return options; } /** * @function * @memberof Popper.Utils * @argument {Object} data - The data object generated by `update` method * @argument {Boolean} shouldRound - If the offsets should be rounded at all * @returns {Object} The popper's position offsets rounded * * The tale of pixel-perfect positioning. It's still not 100% perfect, but as * good as it can be within reason. * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 * * Low DPI screens cause a popper to be blurry if not using full pixels (Safari * as well on High DPI screens). * * Firefox prefers no rounding for positioning and does not have blurriness on * high DPI screens. * * Only horizontal placement and left/right values need to be considered. */ function getRoundedOffsets(data, shouldRound) { var _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var round = Math.round, floor = Math.floor; var noRound = function noRound(v) { return v; }; var referenceWidth = round(reference.width); var popperWidth = round(popper.width); var isVertical = ['left', 'right'].indexOf(data.placement) !== -1; var isVariation = data.placement.indexOf('-') !== -1; var sameWidthParity = referenceWidth % 2 === popperWidth % 2; var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1; var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor; var verticalToInteger = !shouldRound ? noRound : round; return { left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left), top: verticalToInteger(popper.top), bottom: verticalToInteger(popper.bottom), right: horizontalToInteger(popper.right) }; } var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent); /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function computeStyle(data, options) { var x = options.x, y = options.y; var popper = data.offsets.popper; // Remove this legacy support in Popper.js v2 var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { return modifier.name === 'applyStyle'; }).gpuAcceleration; if (legacyGpuAccelerationOption !== undefined) { console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); } var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; var offsetParent = getOffsetParent(data.instance.popper); var offsetParentRect = getBoundingClientRect(offsetParent); // Styles var styles = { position: popper.position }; var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox); var sideA = x === 'bottom' ? 'top' : 'bottom'; var sideB = y === 'right' ? 'left' : 'right'; // if gpuAcceleration is set to `true` and transform is supported, // we use `translate3d` to apply the position to the popper we // automatically use the supported prefixed version if needed var prefixedProperty = getSupportedPropertyName('transform'); // now, let's make a step back and look at this code closely (wtf?) // If the content of the popper grows once it's been positioned, it // may happen that the popper gets misplaced because of the new content // overflowing its reference element // To avoid this problem, we provide two options (x and y), which allow // the consumer to define the offset origin. // If we position a popper on top of a reference element, we can set // `x` to `top` to make the popper grow towards its top instead of // its bottom. var left = void 0, top = void 0; if (sideA === 'bottom') { // when offsetParent is the positioning is relative to the bottom of the screen (excluding the scrollbar) // and not the bottom of the html element if (offsetParent.nodeName === 'HTML') { top = -offsetParent.clientHeight + offsets.bottom; } else { top = -offsetParentRect.height + offsets.bottom; } } else { top = offsets.top; } if (sideB === 'right') { if (offsetParent.nodeName === 'HTML') { left = -offsetParent.clientWidth + offsets.right; } else { left = -offsetParentRect.width + offsets.right; } } else { left = offsets.left; } if (gpuAcceleration && prefixedProperty) { styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; styles[sideA] = 0; styles[sideB] = 0; styles.willChange = 'transform'; } else { // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties var invertTop = sideA === 'bottom' ? -1 : 1; var invertLeft = sideB === 'right' ? -1 : 1; styles[sideA] = top * invertTop; styles[sideB] = left * invertLeft; styles.willChange = sideA + ', ' + sideB; } // Attributes var attributes = { 'x-placement': data.placement }; // Update `data` attributes, styles and arrowStyles data.attributes = _extends({}, attributes, data.attributes); data.styles = _extends({}, styles, data.styles); data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); return data; } /** * Helper used to know if the given modifier depends from another one.
* It checks if the needed modifier is listed and enabled. * @method * @memberof Popper.Utils * @param {Array} modifiers - list of modifiers * @param {String} requestingName - name of requesting modifier * @param {String} requestedName - name of requested modifier * @returns {Boolean} */ function isModifierRequired(modifiers, requestingName, requestedName) { var requesting = find(modifiers, function (_ref) { var name = _ref.name; return name === requestingName; }); var isRequired = !!requesting && modifiers.some(function (modifier) { return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; }); if (!isRequired) { var _requesting = '`' + requestingName + '`'; var requested = '`' + requestedName + '`'; console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); } return isRequired; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function arrow(data, options) { var _data$offsets$arrow; // arrow depends on keepTogether in order to work if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { return data; } var arrowElement = options.element; // if arrowElement is a string, suppose it's a CSS selector if (typeof arrowElement === 'string') { arrowElement = data.instance.popper.querySelector(arrowElement); // if arrowElement is not found, don't run the modifier if (!arrowElement) { return data; } } else { // if the arrowElement isn't a query selector we must check that the // provided DOM node is child of its popper node if (!data.instance.popper.contains(arrowElement)) { console.warn('WARNING: `arrow.element` must be child of its popper element!'); return data; } } var placement = data.placement.split('-')[0]; var _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var isVertical = ['left', 'right'].indexOf(placement) !== -1; var len = isVertical ? 'height' : 'width'; var sideCapitalized = isVertical ? 'Top' : 'Left'; var side = sideCapitalized.toLowerCase(); var altSide = isVertical ? 'left' : 'top'; var opSide = isVertical ? 'bottom' : 'right'; var arrowElementSize = getOuterSizes(arrowElement)[len]; // // extends keepTogether behavior making sure the popper and its // reference have enough pixels in conjunction // // top/left side if (reference[opSide] - arrowElementSize < popper[side]) { data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); } // bottom/right side if (reference[side] + arrowElementSize > popper[opSide]) { data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; } data.offsets.popper = getClientRect(data.offsets.popper); // compute center of the popper var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; // Compute the sideValue using the updated popper offsets // take popper margin in account because we don't have this info available var css = getStyleComputedProperty(data.instance.popper); var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10); var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10); var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; // prevent arrowElement from being placed not contiguously to its popper sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); data.arrowElement = arrowElement; data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); return data; } /** * Get the opposite placement variation of the given one * @method * @memberof Popper.Utils * @argument {String} placement variation * @returns {String} flipped placement variation */ function getOppositeVariation(variation) { if (variation === 'end') { return 'start'; } else if (variation === 'start') { return 'end'; } return variation; } /** * List of accepted placements to use as values of the `placement` option.
* Valid placements are: * - `auto` * - `top` * - `right` * - `bottom` * - `left` * * Each placement can have a variation from this list: * - `-start` * - `-end` * * Variations are interpreted easily if you think of them as the left to right * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` * is right.
* Vertically (`left` and `right`), `start` is top and `end` is bottom. * * Some valid examples are: * - `top-end` (on top of reference, right aligned) * - `right-start` (on right of reference, top aligned) * - `bottom` (on bottom, centered) * - `auto-end` (on the side with more space available, alignment depends by placement) * * @static * @type {Array} * @enum {String} * @readonly * @method placements * @memberof Popper */ var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; // Get rid of `auto` `auto-start` and `auto-end` var validPlacements = placements.slice(3); /** * Given an initial placement, returns all the subsequent placements * clockwise (or counter-clockwise). * * @method * @memberof Popper.Utils * @argument {String} placement - A valid placement (it accepts variations) * @argument {Boolean} counter - Set to true to walk the placements counterclockwise * @returns {Array} placements including their variations */ function clockwise(placement) { var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var index = validPlacements.indexOf(placement); var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); return counter ? arr.reverse() : arr; } var BEHAVIORS = { FLIP: 'flip', CLOCKWISE: 'clockwise', COUNTERCLOCKWISE: 'counterclockwise' }; /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function flip(data, options) { // if `inner` modifier is enabled, we can't use the `flip` modifier if (isModifierEnabled(data.instance.modifiers, 'inner')) { return data; } if (data.flipped && data.placement === data.originalPlacement) { // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides return data; } var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); var placement = data.placement.split('-')[0]; var placementOpposite = getOppositePlacement(placement); var variation = data.placement.split('-')[1] || ''; var flipOrder = []; switch (options.behavior) { case BEHAVIORS.FLIP: flipOrder = [placement, placementOpposite]; break; case BEHAVIORS.CLOCKWISE: flipOrder = clockwise(placement); break; case BEHAVIORS.COUNTERCLOCKWISE: flipOrder = clockwise(placement, true); break; default: flipOrder = options.behavior; } flipOrder.forEach(function (step, index) { if (placement !== step || flipOrder.length === index + 1) { return data; } placement = data.placement.split('-')[0]; placementOpposite = getOppositePlacement(placement); var popperOffsets = data.offsets.popper; var refOffsets = data.offsets.reference; // using floor because the reference offsets may contain decimals we are not going to consider here var floor = Math.floor; var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; // flip the variation if required var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; // flips variation if reference element overflows boundaries var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); // flips variation if popper content overflows boundaries var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop); var flippedVariation = flippedVariationByRef || flippedVariationByContent; if (overlapsRef || overflowsBoundaries || flippedVariation) { // this boolean to detect any flip loop data.flipped = true; if (overlapsRef || overflowsBoundaries) { placement = flipOrder[index + 1]; } if (flippedVariation) { variation = getOppositeVariation(variation); } data.placement = placement + (variation ? '-' + variation : ''); // this object contains `position`, we want to preserve it along with // any additional property we may add in the future data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); data = runModifiers(data.instance.modifiers, data, 'flip'); } }); return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function keepTogether(data) { var _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var placement = data.placement.split('-')[0]; var floor = Math.floor; var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; var side = isVertical ? 'right' : 'bottom'; var opSide = isVertical ? 'left' : 'top'; var measurement = isVertical ? 'width' : 'height'; if (popper[side] < floor(reference[opSide])) { data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; } if (popper[opSide] > floor(reference[side])) { data.offsets.popper[opSide] = floor(reference[side]); } return data; } /** * Converts a string containing value + unit into a px value number * @function * @memberof {modifiers~offset} * @private * @argument {String} str - Value + unit string * @argument {String} measurement - `height` or `width` * @argument {Object} popperOffsets * @argument {Object} referenceOffsets * @returns {Number|String} * Value in pixels, or original string if no values were extracted */ function toValue(str, measurement, popperOffsets, referenceOffsets) { // separate value from unit var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); var value = +split[1]; var unit = split[2]; // If it's not a number it's an operator, I guess if (!value) { return str; } if (unit.indexOf('%') === 0) { var element = void 0; switch (unit) { case '%p': element = popperOffsets; break; case '%': case '%r': default: element = referenceOffsets; } var rect = getClientRect(element); return rect[measurement] / 100 * value; } else if (unit === 'vh' || unit === 'vw') { // if is a vh or vw, we calculate the size based on the viewport var size = void 0; if (unit === 'vh') { size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); } else { size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); } return size / 100 * value; } else { // if is an explicit pixel unit, we get rid of the unit and keep the value // if is an implicit unit, it's px, and we return just the value return value; } } /** * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. * @function * @memberof {modifiers~offset} * @private * @argument {String} offset * @argument {Object} popperOffsets * @argument {Object} referenceOffsets * @argument {String} basePlacement * @returns {Array} a two cells array with x and y offsets in numbers */ function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { var offsets = [0, 0]; // Use height if placement is left or right and index is 0 otherwise use width // in this way the first offset will use an axis and the second one // will use the other one var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; // Split the offset string to obtain a list of values and operands // The regex addresses values with the plus or minus sign in front (+10, -20, etc) var fragments = offset.split(/(\+|\-)/).map(function (frag) { return frag.trim(); }); // Detect if the offset string contains a pair of values or a single one // they could be separated by comma or space var divider = fragments.indexOf(find(fragments, function (frag) { return frag.search(/,|\s/) !== -1; })); if (fragments[divider] && fragments[divider].indexOf(',') === -1) { console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); } // If divider is found, we divide the list of values and operands to divide // them by ofset X and Y. var splitRegex = /\s*,\s*|\s+/; var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; // Convert the values with units to absolute pixels to allow our computations ops = ops.map(function (op, index) { // Most of the units rely on the orientation of the popper var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; var mergeWithPrevious = false; return op // This aggregates any `+` or `-` sign that aren't considered operators // e.g.: 10 + +5 => [10, +, +5] .reduce(function (a, b) { if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { a[a.length - 1] = b; mergeWithPrevious = true; return a; } else if (mergeWithPrevious) { a[a.length - 1] += b; mergeWithPrevious = false; return a; } else { return a.concat(b); } }, []) // Here we convert the string values into number values (in px) .map(function (str) { return toValue(str, measurement, popperOffsets, referenceOffsets); }); }); // Loop trough the offsets arrays and execute the operations ops.forEach(function (op, index) { op.forEach(function (frag, index2) { if (isNumeric(frag)) { offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); } }); }); return offsets; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @argument {Number|String} options.offset=0 * The offset value as described in the modifier description * @returns {Object} The data object, properly modified */ function offset(data, _ref) { var offset = _ref.offset; var placement = data.placement, _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var basePlacement = placement.split('-')[0]; var offsets = void 0; if (isNumeric(+offset)) { offsets = [+offset, 0]; } else { offsets = parseOffset(offset, popper, reference, basePlacement); } if (basePlacement === 'left') { popper.top += offsets[0]; popper.left -= offsets[1]; } else if (basePlacement === 'right') { popper.top += offsets[0]; popper.left += offsets[1]; } else if (basePlacement === 'top') { popper.left += offsets[0]; popper.top -= offsets[1]; } else if (basePlacement === 'bottom') { popper.left += offsets[0]; popper.top += offsets[1]; } data.popper = popper; return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function preventOverflow(data, options) { var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); // If offsetParent is the reference element, we really want to // go one step up and use the next offsetParent as reference to // avoid to make this modifier completely useless and look like broken if (data.instance.reference === boundariesElement) { boundariesElement = getOffsetParent(boundariesElement); } // NOTE: DOM access here // resets the popper's position so that the document size can be calculated excluding // the size of the popper element itself var transformProp = getSupportedPropertyName('transform'); var popperStyles = data.instance.popper.style; // assignment to help minification var top = popperStyles.top, left = popperStyles.left, transform = popperStyles[transformProp]; popperStyles.top = ''; popperStyles.left = ''; popperStyles[transformProp] = ''; var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); // NOTE: DOM access here // restores the original style properties after the offsets have been computed popperStyles.top = top; popperStyles.left = left; popperStyles[transformProp] = transform; options.boundaries = boundaries; var order = options.priority; var popper = data.offsets.popper; var check = { primary: function primary(placement) { var value = popper[placement]; if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { value = Math.max(popper[placement], boundaries[placement]); } return defineProperty({}, placement, value); }, secondary: function secondary(placement) { var mainSide = placement === 'right' ? 'left' : 'top'; var value = popper[mainSide]; if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); } return defineProperty({}, mainSide, value); } }; order.forEach(function (placement) { var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; popper = _extends({}, popper, check[side](placement)); }); data.offsets.popper = popper; return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function shift(data) { var placement = data.placement; var basePlacement = placement.split('-')[0]; var shiftvariation = placement.split('-')[1]; // if shift shiftvariation is specified, run the modifier if (shiftvariation) { var _data$offsets = data.offsets, reference = _data$offsets.reference, popper = _data$offsets.popper; var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; var side = isVertical ? 'left' : 'top'; var measurement = isVertical ? 'width' : 'height'; var shiftOffsets = { start: defineProperty({}, side, reference[side]), end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) }; data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); } return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function hide(data) { if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { return data; } var refRect = data.offsets.reference; var bound = find(data.instance.modifiers, function (modifier) { return modifier.name === 'preventOverflow'; }).boundaries; if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { // Avoid unnecessary DOM access if visibility hasn't changed if (data.hide === true) { return data; } data.hide = true; data.attributes['x-out-of-boundaries'] = ''; } else { // Avoid unnecessary DOM access if visibility hasn't changed if (data.hide === false) { return data; } data.hide = false; data.attributes['x-out-of-boundaries'] = false; } return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function inner(data) { var placement = data.placement; var basePlacement = placement.split('-')[0]; var _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); data.placement = getOppositePlacement(placement); data.offsets.popper = getClientRect(popper); return data; } /** * Modifier function, each modifier can have a function of this type assigned * to its `fn` property.
* These functions will be called on each update, this means that you must * make sure they are performant enough to avoid performance bottlenecks. * * @function ModifierFn * @argument {dataObject} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {dataObject} The data object, properly modified */ /** * Modifiers are plugins used to alter the behavior of your poppers.
* Popper.js uses a set of 9 modifiers to provide all the basic functionalities * needed by the library. * * Usually you don't want to override the `order`, `fn` and `onLoad` props. * All the other properties are configurations that could be tweaked. * @namespace modifiers */ var modifiers = { /** * Modifier used to shift the popper on the start or end of its reference * element.
* It will read the variation of the `placement` property.
* It can be one either `-end` or `-start`. * @memberof modifiers * @inner */ shift: { /** @prop {number} order=100 - Index used to define the order of execution */ order: 100, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: shift }, /** * The `offset` modifier can shift your popper on both its axis. * * It accepts the following units: * - `px` or unit-less, interpreted as pixels * - `%` or `%r`, percentage relative to the length of the reference element * - `%p`, percentage relative to the length of the popper element * - `vw`, CSS viewport width unit * - `vh`, CSS viewport height unit * * For length is intended the main axis relative to the placement of the popper.
* This means that if the placement is `top` or `bottom`, the length will be the * `width`. In case of `left` or `right`, it will be the `height`. * * You can provide a single value (as `Number` or `String`), or a pair of values * as `String` divided by a comma or one (or more) white spaces.
* The latter is a deprecated method because it leads to confusion and will be * removed in v2.
* Additionally, it accepts additions and subtractions between different units. * Note that multiplications and divisions aren't supported. * * Valid examples are: * ``` * 10 * '10%' * '10, 10' * '10%, 10' * '10 + 10%' * '10 - 5vh + 3%' * '-10px + 5vh, 5px - 6%' * ``` * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap * > with their reference element, unfortunately, you will have to disable the `flip` modifier. * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). * * @memberof modifiers * @inner */ offset: { /** @prop {number} order=200 - Index used to define the order of execution */ order: 200, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: offset, /** @prop {Number|String} offset=0 * The offset value as described in the modifier description */ offset: 0 }, /** * Modifier used to prevent the popper from being positioned outside the boundary. * * A scenario exists where the reference itself is not within the boundaries.
* We can say it has "escaped the boundaries" — or just "escaped".
* In this case we need to decide whether the popper should either: * * - detach from the reference and remain "trapped" in the boundaries, or * - if it should ignore the boundary and "escape with its reference" * * When `escapeWithReference` is set to`true` and reference is completely * outside its boundaries, the popper will overflow (or completely leave) * the boundaries in order to remain attached to the edge of the reference. * * @memberof modifiers * @inner */ preventOverflow: { /** @prop {number} order=300 - Index used to define the order of execution */ order: 300, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: preventOverflow, /** * @prop {Array} [priority=['left','right','top','bottom']] * Popper will try to prevent overflow following these priorities by default, * then, it could overflow on the left and on top of the `boundariesElement` */ priority: ['left', 'right', 'top', 'bottom'], /** * @prop {number} padding=5 * Amount of pixel used to define a minimum distance between the boundaries * and the popper. This makes sure the popper always has a little padding * between the edges of its container */ padding: 5, /** * @prop {String|HTMLElement} boundariesElement='scrollParent' * Boundaries used by the modifier. Can be `scrollParent`, `window`, * `viewport` or any DOM element. */ boundariesElement: 'scrollParent' }, /** * Modifier used to make sure the reference and its popper stay near each other * without leaving any gap between the two. Especially useful when the arrow is * enabled and you want to ensure that it points to its reference element. * It cares only about the first axis. You can still have poppers with margin * between the popper and its reference element. * @memberof modifiers * @inner */ keepTogether: { /** @prop {number} order=400 - Index used to define the order of execution */ order: 400, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: keepTogether }, /** * This modifier is used to move the `arrowElement` of the popper to make * sure it is positioned between the reference element and its popper element. * It will read the outer size of the `arrowElement` node to detect how many * pixels of conjunction are needed. * * It has no effect if no `arrowElement` is provided. * @memberof modifiers * @inner */ arrow: { /** @prop {number} order=500 - Index used to define the order of execution */ order: 500, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: arrow, /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ element: '[x-arrow]' }, /** * Modifier used to flip the popper's placement when it starts to overlap its * reference element. * * Requires the `preventOverflow` modifier before it in order to work. * * **NOTE:** this modifier will interrupt the current update cycle and will * restart it if it detects the need to flip the placement. * @memberof modifiers * @inner */ flip: { /** @prop {number} order=600 - Index used to define the order of execution */ order: 600, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: flip, /** * @prop {String|Array} behavior='flip' * The behavior used to change the popper's placement. It can be one of * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid * placements (with optional variations) */ behavior: 'flip', /** * @prop {number} padding=5 * The popper will flip if it hits the edges of the `boundariesElement` */ padding: 5, /** * @prop {String|HTMLElement} boundariesElement='viewport' * The element which will define the boundaries of the popper position. * The popper will never be placed outside of the defined boundaries * (except if `keepTogether` is enabled) */ boundariesElement: 'viewport', /** * @prop {Boolean} flipVariations=false * The popper will switch placement variation between `-start` and `-end` when * the reference element overlaps its boundaries. * * The original placement should have a set variation. */ flipVariations: false, /** * @prop {Boolean} flipVariationsByContent=false * The popper will switch placement variation between `-start` and `-end` when * the popper element overlaps its reference boundaries. * * The original placement should have a set variation. */ flipVariationsByContent: false }, /** * Modifier used to make the popper flow toward the inner of the reference element. * By default, when this modifier is disabled, the popper will be placed outside * the reference element. * @memberof modifiers * @inner */ inner: { /** @prop {number} order=700 - Index used to define the order of execution */ order: 700, /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ enabled: false, /** @prop {ModifierFn} */ fn: inner }, /** * Modifier used to hide the popper when its reference element is outside of the * popper boundaries. It will set a `x-out-of-boundaries` attribute which can * be used to hide with a CSS selector the popper when its reference is * out of boundaries. * * Requires the `preventOverflow` modifier before it in order to work. * @memberof modifiers * @inner */ hide: { /** @prop {number} order=800 - Index used to define the order of execution */ order: 800, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: hide }, /** * Computes the style that will be applied to the popper element to gets * properly positioned. * * Note that this modifier will not touch the DOM, it just prepares the styles * so that `applyStyle` modifier can apply it. This separation is useful * in case you need to replace `applyStyle` with a custom implementation. * * This modifier has `850` as `order` value to maintain backward compatibility * with previous versions of Popper.js. Expect the modifiers ordering method * to change in future major versions of the library. * * @memberof modifiers * @inner */ computeStyle: { /** @prop {number} order=850 - Index used to define the order of execution */ order: 850, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: computeStyle, /** * @prop {Boolean} gpuAcceleration=true * If true, it uses the CSS 3D transformation to position the popper. * Otherwise, it will use the `top` and `left` properties */ gpuAcceleration: true, /** * @prop {string} [x='bottom'] * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. * Change this if your popper should grow in a direction different from `bottom` */ x: 'bottom', /** * @prop {string} [x='left'] * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. * Change this if your popper should grow in a direction different from `right` */ y: 'right' }, /** * Applies the computed styles to the popper element. * * All the DOM manipulations are limited to this modifier. This is useful in case * you want to integrate Popper.js inside a framework or view library and you * want to delegate all the DOM manipulations to it. * * Note that if you disable this modifier, you must make sure the popper element * has its position set to `absolute` before Popper.js can do its work! * * Just disable this modifier and define your own to achieve the desired effect. * * @memberof modifiers * @inner */ applyStyle: { /** @prop {number} order=900 - Index used to define the order of execution */ order: 900, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: applyStyle, /** @prop {Function} */ onLoad: applyStyleOnLoad, /** * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier * @prop {Boolean} gpuAcceleration=true * If true, it uses the CSS 3D transformation to position the popper. * Otherwise, it will use the `top` and `left` properties */ gpuAcceleration: undefined } }; /** * The `dataObject` is an object containing all the information used by Popper.js. * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. * @name dataObject * @property {Object} data.instance The Popper.js instance * @property {String} data.placement Placement applied to popper * @property {String} data.originalPlacement Placement originally defined on init * @property {Boolean} data.flipped True if popper has been flipped by flip modifier * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) * @property {Object} data.boundaries Offsets of the popper boundaries * @property {Object} data.offsets The measurements of popper, reference and arrow elements * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 */ /** * Default options provided to Popper.js constructor.
* These can be overridden using the `options` argument of Popper.js.
* To override an option, simply pass an object with the same * structure of the `options` object, as the 3rd argument. For example: * ``` * new Popper(ref, pop, { * modifiers: { * preventOverflow: { enabled: false } * } * }) * ``` * @type {Object} * @static * @memberof Popper */ var Defaults = { /** * Popper's placement. * @prop {Popper.placements} placement='bottom' */ placement: 'bottom', /** * Set this to true if you want popper to position it self in 'fixed' mode * @prop {Boolean} positionFixed=false */ positionFixed: false, /** * Whether events (resize, scroll) are initially enabled. * @prop {Boolean} eventsEnabled=true */ eventsEnabled: true, /** * Set to true if you want to automatically remove the popper when * you call the `destroy` method. * @prop {Boolean} removeOnDestroy=false */ removeOnDestroy: false, /** * Callback called when the popper is created.
* By default, it is set to no-op.
* Access Popper.js instance with `data.instance`. * @prop {onCreate} */ onCreate: function onCreate() {}, /** * Callback called when the popper is updated. This callback is not called * on the initialization/creation of the popper, but only on subsequent * updates.
* By default, it is set to no-op.
* Access Popper.js instance with `data.instance`. * @prop {onUpdate} */ onUpdate: function onUpdate() {}, /** * List of modifiers used to modify the offsets before they are applied to the popper. * They provide most of the functionalities of Popper.js. * @prop {modifiers} */ modifiers: modifiers }; /** * @callback onCreate * @param {dataObject} data */ /** * @callback onUpdate * @param {dataObject} data */ // Utils // Methods var Popper = function () { /** * Creates a new Popper.js instance. * @class Popper * @param {Element|referenceObject} reference - The reference element used to position the popper * @param {Element} popper - The HTML / XML element used as the popper * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) * @return {Object} instance - The generated Popper.js instance */ function Popper(reference, popper) { var _this = this; var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; classCallCheck(this, Popper); this.scheduleUpdate = function () { return requestAnimationFrame(_this.update); }; // make update() debounced, so that it only runs at most once-per-tick this.update = debounce(this.update.bind(this)); // with {} we create a new object with the options inside it this.options = _extends({}, Popper.Defaults, options); // init state this.state = { isDestroyed: false, isCreated: false, scrollParents: [] }; // get reference and popper elements (allow jQuery wrappers) this.reference = reference && reference.jquery ? reference[0] : reference; this.popper = popper && popper.jquery ? popper[0] : popper; // Deep merge modifiers options this.options.modifiers = {}; Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); }); // Refactoring modifiers' list (Object => Array) this.modifiers = Object.keys(this.options.modifiers).map(function (name) { return _extends({ name: name }, _this.options.modifiers[name]); }) // sort the modifiers by order .sort(function (a, b) { return a.order - b.order; }); // modifiers have the ability to execute arbitrary code when Popper.js get inited // such code is executed in the same order of its modifier // they could add new properties to their options configuration // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! this.modifiers.forEach(function (modifierOptions) { if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); } }); // fire the first update to position the popper in the right place this.update(); var eventsEnabled = this.options.eventsEnabled; if (eventsEnabled) { // setup event listeners, they will take care of update the position in specific situations this.enableEventListeners(); } this.state.eventsEnabled = eventsEnabled; } // We can't use class properties because they don't get listed in the // class prototype and break stuff like Sinon stubs createClass(Popper, [{ key: 'update', value: function update$$1() { return update.call(this); } }, { key: 'destroy', value: function destroy$$1() { return destroy.call(this); } }, { key: 'enableEventListeners', value: function enableEventListeners$$1() { return enableEventListeners.call(this); } }, { key: 'disableEventListeners', value: function disableEventListeners$$1() { return disableEventListeners.call(this); } /** * Schedules an update. It will run on the next UI update available. * @method scheduleUpdate * @memberof Popper */ /** * Collection of utilities useful when writing custom modifiers. * Starting from version 1.7, this method is available only if you * include `popper-utils.js` before `popper.js`. * * **DEPRECATION**: This way to access PopperUtils is deprecated * and will be removed in v2! Use the PopperUtils module directly instead. * Due to the high instability of the methods contained in Utils, we can't * guarantee them to follow semver. Use them at your own risk! * @static * @private * @type {Object} * @deprecated since version 1.8 * @member Utils * @memberof Popper */ }]); return Popper; }(); /** * The `referenceObject` is an object that provides an interface compatible with Popper.js * and lets you use it as replacement of a real DOM node.
* You can use this method to position a popper relatively to a set of coordinates * in case you don't have a DOM node to use as reference. * * ``` * new Popper(referenceObject, popperNode); * ``` * * NB: This feature isn't supported in Internet Explorer 10. * @name referenceObject * @property {Function} data.getBoundingClientRect * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. * @property {number} data.clientWidth * An ES6 getter that will return the width of the virtual reference element. * @property {number} data.clientHeight * An ES6 getter that will return the height of the virtual reference element. */ Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; Popper.placements = placements; Popper.Defaults = Defaults; return Popper; }))); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],6:[function(require,module,exports){ (function (process){ /**! * tippy.js v5.1.4 * (c) 2017-2020 atomiks * MIT License */ 'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var Popper = _interopDefault(require('popper.js')); function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } var version = "5.1.4"; /** * Triggers reflow */ function reflow(element) { void element.offsetHeight; } /** * Sets the innerHTML of an element */ function setInnerHTML(element, html) { element[innerHTML()] = html; } /** * Determines if the value is a reference element */ function isReferenceElement(value) { return !!(value && value._tippy && value._tippy.reference === value); } /** * Safe .hasOwnProperty check, for prototype-less objects */ function hasOwnProperty(obj, key) { return {}.hasOwnProperty.call(obj, key); } /** * Returns an array of elements based on the value */ function getArrayOfElements(value) { if (isElement(value)) { return [value]; } if (isNodeList(value)) { return arrayFrom(value); } if (Array.isArray(value)) { return value; } return arrayFrom(document.querySelectorAll(value)); } /** * Returns a value at a given index depending on if it's an array or number */ function getValueAtIndexOrReturn(value, index, defaultValue) { if (Array.isArray(value)) { var v = value[index]; return v == null ? Array.isArray(defaultValue) ? defaultValue[index] : defaultValue : v; } return value; } /** * Prevents errors from being thrown while accessing nested modifier objects * in `popperOptions` */ function getModifier(obj, key) { return obj && obj.modifiers && obj.modifiers[key]; } /** * Determines if the value is of type */ function isType(value, type) { var str = {}.toString.call(value); return str.indexOf('[object') === 0 && str.indexOf(type + "]") > -1; } /** * Determines if the value is of type Element */ function isElement(value) { return isType(value, 'Element'); } /** * Determines if the value is of type NodeList */ function isNodeList(value) { return isType(value, 'NodeList'); } /** * Determines if the value is of type MouseEvent */ function isMouseEvent(value) { return isType(value, 'MouseEvent'); } /** * Firefox extensions don't allow setting .innerHTML directly, this will trick * it */ function innerHTML() { return 'innerHTML'; } /** * Evaluates a function if one, or returns the value */ function invokeWithArgsOrReturn(value, args) { return typeof value === 'function' ? value.apply(void 0, args) : value; } /** * Sets a popperInstance modifier's property to a value */ function setModifierValue(modifiers, name, property, value) { modifiers.filter(function (m) { return m.name === name; })[0][property] = value; } /** * Returns a new `div` element */ function div() { return document.createElement('div'); } /** * Applies a transition duration to a list of elements */ function setTransitionDuration(els, value) { els.forEach(function (el) { if (el) { el.style.transitionDuration = value + "ms"; } }); } /** * Sets the visibility state to elements so they can begin to transition */ function setVisibilityState(els, state) { els.forEach(function (el) { if (el) { el.setAttribute('data-state', state); } }); } /** * Debounce utility. To avoid bloating bundle size, we're only passing 1 * argument here, a more generic function would pass all arguments. Only * `onMouseMove` uses this which takes the event object for now. */ function debounce(fn, ms) { // Avoid wrapping in `setTimeout` if ms is 0 anyway if (ms === 0) { return fn; } var timeout; return function (arg) { clearTimeout(timeout); timeout = setTimeout(function () { fn(arg); }, ms); }; } /** * Preserves the original function invocation when another function replaces it */ function preserveInvocation(originalFn, currentFn, args) { if (originalFn && originalFn !== currentFn) { originalFn.apply(void 0, args); } } /** * Deletes properties from an object (pure) */ function removeProperties(obj, keys) { var clone = _extends({}, obj); keys.forEach(function (key) { delete clone[key]; }); return clone; } /** * Ponyfill for Array.from - converts iterable values to an array */ function arrayFrom(value) { return [].slice.call(value); } /** * Works like Element.prototype.closest, but uses a callback instead */ function closestCallback(element, callback) { while (element) { if (callback(element)) { return element; } element = element.parentElement; } return null; } /** * Determines if an array or string includes a string */ function includes(a, b) { return a.indexOf(b) > -1; } /** * Creates an array from string of values separated by whitespace */ function splitBySpaces(value) { return value.split(/\s+/).filter(Boolean); } /** * Returns the `nextValue` if `nextValue` is not `undefined`, otherwise returns * `currentValue` */ function useIfDefined(nextValue, currentValue) { return nextValue !== undefined ? nextValue : currentValue; } /** * Converts a value that's an array or single value to an array */ function normalizeToArray(value) { return [].concat(value); } /** * Returns the ownerDocument of the first available element, otherwise global * document */ function getOwnerDocument(elementOrElements) { var _normalizeToArray = normalizeToArray(elementOrElements), element = _normalizeToArray[0]; return element ? element.ownerDocument || document : document; } /** * Adds item to array if array does not contain it */ function pushIfUnique(arr, value) { if (arr.indexOf(value) === -1) { arr.push(value); } } /** * Adds `px` if value is a number, or returns it directly */ function appendPxIfNumber(value) { return typeof value === 'number' ? value + "px" : value; } /** * Filters out duplicate elements in an array */ function unique(arr) { return arr.filter(function (item, index) { return arr.indexOf(item) === index; }); } /** * Returns number from number or CSS units string */ function getNumber(value) { return typeof value === 'number' ? value : parseFloat(value); } /** * Gets number or CSS string units in pixels (e.g. `1rem` -> 16) */ function getUnitsInPx(doc, value) { var isRem = typeof value === 'string' && includes(value, 'rem'); var html = doc.documentElement; var rootFontSize = 16; if (html && isRem) { return parseFloat(getComputedStyle(html).fontSize || String(rootFontSize)) * getNumber(value); } return getNumber(value); } /** * Adds the `distancePx` value to the placement of a Popper.Padding object */ function getComputedPadding(basePlacement, padding, distancePx) { if (padding === void 0) { padding = 5; } var freshPaddingObject = { top: 0, right: 0, bottom: 0, left: 0 }; var keys = Object.keys(freshPaddingObject); return keys.reduce(function (obj, key) { obj[key] = typeof padding === 'number' ? padding : padding[key]; if (basePlacement === key) { obj[key] = typeof padding === 'number' ? padding + distancePx : padding[basePlacement] + distancePx; } return obj; }, freshPaddingObject); } function createMemoryLeakWarning(method) { var txt = method === 'destroy' ? 'n already-' : ' '; return "\n " + method + "() was called on a" + txt + "destroyed instance. This is a no-op but\n indicates a potential memory leak.\n "; } function clean(value) { var spacesAndTabs = /[ \t]{2,}/g; var lineStartWithSpaces = /^[ \t]*/gm; return value.replace(spacesAndTabs, ' ').replace(lineStartWithSpaces, '').trim(); } function getDevMessage(message) { return clean("\n %ctippy.js\n\n %c" + clean(message) + "\n\n %c\uD83D\uDC77\u200D This is a development-only message. It will be removed in production.\n "); } function getFormattedMessage(message) { return [getDevMessage(message), // title 'color: #00C584; font-size: 1.3em; font-weight: bold;', // message 'line-height: 1.5', // footer 'color: #a6a095;']; } /** * Helpful wrapper around `console.warn()`. * TODO: Should we use a cache so it only warns a single time and not spam the * console? (Need to consider hot reloading and invalidation though). Chrome * already batches warnings as well. */ function warnWhen(condition, message) { if (condition) { var _console; (_console = console).warn.apply(_console, getFormattedMessage(message)); } } /** * Helpful wrapper around `console.error()` */ function errorWhen(condition, message) { if (condition) { var _console2; (_console2 = console).error.apply(_console2, getFormattedMessage(message)); } } /** * Validates the `targets` value passed to `tippy()` */ function validateTargets(targets) { var didPassFalsyValue = !targets; var didPassPlainObject = Object.prototype.toString.call(targets) === '[object Object]' && !targets.addEventListener; errorWhen(didPassFalsyValue, ['tippy() was passed', '`' + String(targets) + '`', 'as its targets (first) argument. Valid types are: String, Element, Element[],', 'or NodeList.'].join(' ')); errorWhen(didPassPlainObject, ['tippy() was passed a plain object which is no longer supported as an argument.', 'See: https://atomiks.github.io/tippyjs/misc/#custom-position'].join(' ')); } var pluginProps = { animateFill: false, followCursor: false, inlinePositioning: false, sticky: false }; var defaultProps = _extends({ allowHTML: true, animation: 'fade', appendTo: function appendTo() { return document.body; }, aria: 'describedby', arrow: true, boundary: 'scrollParent', content: '', delay: 0, distance: 10, duration: [300, 250], flip: true, flipBehavior: 'flip', flipOnUpdate: false, hideOnClick: true, ignoreAttributes: false, inertia: false, interactive: false, interactiveBorder: 2, interactiveDebounce: 0, lazy: true, maxWidth: 350, multiple: false, offset: 0, onAfterUpdate: function onAfterUpdate() {}, onBeforeUpdate: function onBeforeUpdate() {}, onCreate: function onCreate() {}, onDestroy: function onDestroy() {}, onHidden: function onHidden() {}, onHide: function onHide() {}, onMount: function onMount() {}, onShow: function onShow() {}, onShown: function onShown() {}, onTrigger: function onTrigger() {}, onUntrigger: function onUntrigger() {}, placement: 'top', plugins: [], popperOptions: {}, role: 'tooltip', showOnCreate: false, theme: '', touch: true, trigger: 'mouseenter focus', triggerTarget: null, updateDuration: 0, zIndex: 9999 }, pluginProps); var defaultKeys = Object.keys(defaultProps); /** * If the setProps() method encounters one of these, the popperInstance must be * recreated */ var POPPER_INSTANCE_DEPENDENCIES = ['arrow', 'boundary', 'distance', 'flip', 'flipBehavior', 'flipOnUpdate', 'offset', 'placement', 'popperOptions']; /** * Mutates the defaultProps object by setting the props specified */ var setDefaultProps = function setDefaultProps(partialProps) { if (process.env.NODE_ENV !== "production") { validateProps(partialProps, []); } var keys = Object.keys(partialProps); keys.forEach(function (key) { defaultProps[key] = partialProps[key]; }); }; /** * Returns an extended props object including plugin props */ function getExtendedPassedProps(passedProps) { var plugins = passedProps.plugins || []; var pluginProps = plugins.reduce(function (acc, plugin) { var name = plugin.name, defaultValue = plugin.defaultValue; if (name) { acc[name] = passedProps[name] !== undefined ? passedProps[name] : defaultValue; } return acc; }, {}); return _extends({}, passedProps, {}, pluginProps); } /** * Returns an object of optional props from data-tippy-* attributes */ function getDataAttributeProps(reference, plugins) { var propKeys = plugins ? Object.keys(getExtendedPassedProps(_extends({}, defaultProps, { plugins: plugins }))) : defaultKeys; var props = propKeys.reduce(function (acc, key) { var valueAsString = (reference.getAttribute("data-tippy-" + key) || '').trim(); if (!valueAsString) { return acc; } if (key === 'content') { acc[key] = valueAsString; } else { try { acc[key] = JSON.parse(valueAsString); } catch (e) { acc[key] = valueAsString; } } return acc; }, {}); return props; } /** * Evaluates the props object by merging data attributes and disabling * conflicting props where necessary */ function evaluateProps(reference, props) { var out = _extends({}, props, { content: invokeWithArgsOrReturn(props.content, [reference]) }, props.ignoreAttributes ? {} : getDataAttributeProps(reference, props.plugins)); if (out.interactive) { out.aria = null; } return out; } /** * Validates props with the valid `defaultProps` object */ function validateProps(partialProps, plugins) { if (partialProps === void 0) { partialProps = {}; } if (plugins === void 0) { plugins = []; } var keys = Object.keys(partialProps); keys.forEach(function (prop) { var value = partialProps[prop]; var didSpecifyPlacementInPopperOptions = prop === 'popperOptions' && value !== null && typeof value === 'object' && hasOwnProperty(value, 'placement'); var nonPluginProps = removeProperties(defaultProps, ['animateFill', 'followCursor', 'inlinePositioning', 'sticky']); // These props have custom warnings var customWarningProps = ['a11y', 'arrowType', 'showOnInit', 'size', 'target', 'touchHold']; var didPassUnknownProp = !hasOwnProperty(nonPluginProps, prop) && !includes(customWarningProps, prop); // Check if the prop exists in `plugins` if (didPassUnknownProp) { didPassUnknownProp = plugins.filter(function (plugin) { return plugin.name === prop; }).length === 0; } warnWhen(prop === 'target', ['The `target` prop was removed in v5 and replaced with the delegate() addon', 'in order to conserve bundle size.', 'See: https://atomiks.github.io/tippyjs/addons/#event-delegation'].join(' ')); warnWhen(prop === 'a11y', ['The `a11y` prop was removed in v5. Make sure the element you are giving a', 'tippy to is natively focusable, such as