UNPKG

liftie

Version:

Clean, simple, easy to read, fast ski resort lift status

1,595 lines (1,566 loc) 43.8 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __typeError = (msg) => { throw TypeError(msg); }; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); // node_modules/.pnpm/component-emitter@2.0.0/node_modules/component-emitter/index.js var require_component_emitter = __commonJS({ "node_modules/.pnpm/component-emitter@2.0.0/node_modules/component-emitter/index.js"(exports, module) { function Emitter3(object) { if (object) { return mixin(object); } this._callbacks = /* @__PURE__ */ new Map(); } function mixin(object) { Object.assign(object, Emitter3.prototype); object._callbacks = /* @__PURE__ */ new Map(); return object; } Emitter3.prototype.on = function(event, listener) { var _a; const callbacks = (_a = this._callbacks.get(event)) != null ? _a : []; callbacks.push(listener); this._callbacks.set(event, callbacks); return this; }; Emitter3.prototype.once = function(event, listener) { const on = (...arguments_) => { this.off(event, on); listener.apply(this, arguments_); }; on.fn = listener; this.on(event, on); return this; }; Emitter3.prototype.off = function(event, listener) { if (event === void 0 && listener === void 0) { this._callbacks.clear(); return this; } if (listener === void 0) { this._callbacks.delete(event); return this; } const callbacks = this._callbacks.get(event); if (callbacks) { for (const [index, callback] of callbacks.entries()) { if (callback === listener || callback.fn === listener) { callbacks.splice(index, 1); break; } } if (callbacks.length === 0) { this._callbacks.delete(event); } else { this._callbacks.set(event, callbacks); } } return this; }; Emitter3.prototype.emit = function(event, ...arguments_) { const callbacks = this._callbacks.get(event); if (callbacks) { const callbacksCopy = [...callbacks]; for (const callback of callbacksCopy) { callback.apply(this, arguments_); } } return this; }; Emitter3.prototype.listeners = function(event) { var _a; return (_a = this._callbacks.get(event)) != null ? _a : []; }; Emitter3.prototype.listenerCount = function(event) { if (event) { return this.listeners(event).length; } let totalCount = 0; for (const callbacks of this._callbacks.values()) { totalCount += callbacks.length; } return totalCount; }; Emitter3.prototype.hasListeners = function(event) { return this.listenerCount(event) > 0; }; Emitter3.prototype.addEventListener = Emitter3.prototype.on; Emitter3.prototype.removeListener = Emitter3.prototype.off; Emitter3.prototype.removeEventListener = Emitter3.prototype.off; Emitter3.prototype.removeAllListeners = Emitter3.prototype.off; if (typeof module !== "undefined") { module.exports = Emitter3; } } }); // node_modules/.pnpm/yields-keycode@1.1.0/node_modules/yields-keycode/index.js var require_yields_keycode = __commonJS({ "node_modules/.pnpm/yields-keycode@1.1.0/node_modules/yields-keycode/index.js"(exports, module) { var map = { backspace: 8, command: 91, tab: 9, clear: 12, enter: 13, shift: 16, ctrl: 17, alt: 18, capslock: 20, escape: 27, esc: 27, space: 32, pageup: 33, pagedown: 34, end: 35, home: 36, left: 37, up: 38, right: 39, down: 40, del: 46, comma: 188, f1: 112, f2: 113, f3: 114, f4: 115, f5: 116, f6: 117, f7: 118, f8: 119, f9: 120, f10: 121, f11: 122, f12: 123, ",": 188, ".": 190, "/": 191, "`": 192, "-": 189, "=": 187, ";": 186, "[": 219, "\\": 220, "]": 221, "'": 222 }; module.exports = function(name) { return map[name.toLowerCase()] || name.toUpperCase().charCodeAt(0); }; } }); // node_modules/.pnpm/yields-k-sequence@0.1.0/node_modules/yields-k-sequence/index.js var require_yields_k_sequence = __commonJS({ "node_modules/.pnpm/yields-k-sequence@0.1.0/node_modules/yields-k-sequence/index.js"(exports, module) { var keycode = require_yields_keycode(); module.exports = sequence; function sequence(keys, ms, fn) { var codes = keys.split(/ +/).map(keycode), clen = codes.length, seq = [], i = 0, prev; if (2 == arguments.length) { fn = ms; ms = 500; } return function(e) { var code = codes[i++]; if (42 != code && code != e.which) return reset(); if (prev && /* @__PURE__ */ new Date() - prev > ms) return reset(); var len = seq.push(e.which); prev = /* @__PURE__ */ new Date(); if (len != clen) return; reset(); fn(e); }; function reset() { prev = null; seq = []; i = 0; } } } }); // node_modules/.pnpm/component-os@0.0.1/node_modules/component-os/index.js var require_component_os = __commonJS({ "node_modules/.pnpm/component-os@0.0.1/node_modules/component-os/index.js"(exports, module) { module.exports = os(); function os() { var ua = navigator.userAgent; if (/mac/i.test(ua)) return "mac"; if (/win/i.test(ua)) return "windows"; if (/linux/i.test(ua)) return "linux"; } } }); // node_modules/.pnpm/@pirxpilot+k@1.0.1/node_modules/@pirxpilot/k/lib/proto.js var require_proto = __commonJS({ "node_modules/.pnpm/@pirxpilot+k@1.0.1/node_modules/@pirxpilot/k/lib/proto.js"(exports) { var sequence = require_yields_k_sequence(); var keycode = require_yields_keycode(); var os = require_component_os(); var modifiers = { 224: "command", 91: "command", 93: "command", 16: "shift", 17: "ctrl", 18: "alt" }; exports["super"] = "mac" == os ? "command" : "ctrl"; exports.handle = function(e, fn) { var ignore = this.ignore; var event = e.type; var code = e.which; if (fn) return this.bind(e, fn); var mod = modifiers[code]; if ("keydown" == event && mod) { this["super"] = exports["super"] == mod; this[mod] = true; this.modifiers = true; this.active++; return; } if (ignore && ignore(e)) return; var all = this.listeners; for (var i = 0; i < all.length; ++i) { var invoke = true; var obj = all[i]; var seq = obj.seq; var mods = obj.mods; fn = seq || obj.fn; if (!seq && code != obj.code) continue; if (event != obj.event) continue; if (this.active != obj.mods.length) continue; for (var j = 0; j < mods.length; ++j) { if (!this[mods[j]]) { invoke = null; break; } } if (invoke) { fn(e); } } }; exports.destroy = function() { this.el.removeEventListener("keydown", this._handle); this.el.removeEventListener("keyup", this._handle); this.el.removeEventListener("keyup", this._clear); this.el.removeEventListener("focus", this._clear); this.listeners = []; }; exports.unbind = function(keys, fn) { var fns = this.listeners; var len = fns.length; var all; if (0 === arguments.length) { this.listeners = []; return this; } all = parseKeys(keys); for (var i = 0; i < all.length; ++i) { for (var j = 0, obj; j < len; ++j) { obj = fns[j]; if (!obj) continue; if (fn && obj.fn != fn) continue; if (obj.key != all[i].key) continue; if (!matches(obj, all[i])) continue; fns.splice(j--, 1); } } return this; }; exports.bind = function(event, keys, fn) { var fns = this.listeners; var len; var all; if (2 == arguments.length) { fn = keys; keys = event; event = "keydown"; } all = parseKeys(keys); len = all.length; for (var i = 0; i < len; ++i) { var obj = all[i]; obj.seq = obj.seq && sequence(obj.key, fn); obj.event = event; obj.fn = fn; fns.push(obj); } return this; }; exports.up = function(keys, fn) { return this.bind("keyup", keys, fn); }; exports.down = function(keys, fn) { return this.bind("keydown", keys, fn); }; exports.clear = function(e) { var code = e.keyCode || e.which; if (!(code in modifiers)) return; this.active--; this[modifiers[code]] = null; this.modifiers = this.command || this.shift || this.ctrl || this.alt; }; exports.reset = function() { this.active = 0; this.modifiers = this.command = this.shift = this.ctrl = this.alt = null; }; exports.ignore = function(e) { var el = e.target || e.srcElement; var name = el.tagName.toLowerCase(); return "textarea" == name || "select" == name || "input" == name; }; function parseKeys(keys) { keys = keys.replace("super", exports["super"]); var all = "," != keys ? keys.split(/ *, */) : [","]; var ret = []; for (var i = 0; i < all.length; ++i) { if ("" === all[i]) continue; var mods = all[i].split(/ *\+ */); var key = mods.pop() || ","; ret.push({ seq: !!(~key.indexOf(" ") || ~key.indexOf("*")), code: keycode(key), mods, key }); } return ret; } function matches(a, b) { return 0 === b.mods.length || eql(a, b); } function eql(a, b) { a = a.mods.sort().toString(); b = b.mods.sort().toString(); return a == b; } } }); // node_modules/.pnpm/@pirxpilot+k@1.0.1/node_modules/@pirxpilot/k/lib/index.js var require_lib = __commonJS({ "node_modules/.pnpm/@pirxpilot+k@1.0.1/node_modules/@pirxpilot/k/lib/index.js"(exports, module) { var proto = require_proto(); module.exports = function(el) { function k2(e, fn) { k2.handle(e, fn); } k2._handle = proto.handle.bind(k2); k2._clear = proto.clear.bind(k2); k2._reset = proto.reset.bind(k2); el.addEventListener("keydown", k2._handle, false); el.addEventListener("keyup", k2._handle, false); el.addEventListener("keyup", k2._clear, false); el.addEventListener("focus", k2._reset, false); for (var p in proto) k2[p] = proto[p]; k2.listeners = []; k2.active = 0; k2.el = el; return k2; }; } }); // node_modules/.pnpm/js-cookie@3.0.5/node_modules/js-cookie/dist/js.cookie.mjs function assign(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { target[key] = source[key]; } } return target; } var defaultConverter = { read: function(value) { if (value[0] === '"') { value = value.slice(1, -1); } return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent); }, write: function(value) { return encodeURIComponent(value).replace( /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, decodeURIComponent ); } }; function init(converter, defaultAttributes) { function set(name, value, attributes) { if (typeof document === "undefined") { return; } attributes = assign({}, defaultAttributes, attributes); if (typeof attributes.expires === "number") { attributes.expires = new Date(Date.now() + attributes.expires * 864e5); } if (attributes.expires) { attributes.expires = attributes.expires.toUTCString(); } name = encodeURIComponent(name).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape); var stringifiedAttributes = ""; for (var attributeName in attributes) { if (!attributes[attributeName]) { continue; } stringifiedAttributes += "; " + attributeName; if (attributes[attributeName] === true) { continue; } stringifiedAttributes += "=" + attributes[attributeName].split(";")[0]; } return document.cookie = name + "=" + converter.write(value, name) + stringifiedAttributes; } function get(name) { if (typeof document === "undefined" || arguments.length && !name) { return; } var cookies = document.cookie ? document.cookie.split("; ") : []; var jar = {}; for (var i = 0; i < cookies.length; i++) { var parts = cookies[i].split("="); var value = parts.slice(1).join("="); try { var found = decodeURIComponent(parts[0]); jar[found] = converter.read(value, found); if (name === found) { break; } } catch (e) { } } return name ? jar[name] : jar; } return Object.create( { set, get, remove: function(name, attributes) { set( name, "", assign({}, attributes, { expires: -1 }) ); }, withAttributes: function(attributes) { return init(this.converter, assign({}, this.attributes, attributes)); }, withConverter: function(converter2) { return init(assign({}, this.converter, converter2), this.attributes); } }, { attributes: { value: Object.freeze(defaultAttributes) }, converter: { value: Object.freeze(converter) } } ); } var api = init(defaultConverter, { path: "/" }); // lib/client/about/index.js function about() { const s = document.querySelector(".hidden .about"); if (!s) { return; } if (!check()) { return; } const section = s.parentNode; const trigger = s.querySelector("a.close"); trigger.addEventListener("click", (e) => { close(); e.preventDefault(); }); open(); function check() { return window.parent === window && typeof api.get("resorts-open") === "undefined"; } function close() { section.classList.add("hidden"); } function open() { section.classList.remove("hidden"); } } // lib/client/minimax/index.js function minimax(node, selector) { const my = { trigger: node.querySelector(selector), state: "open", // by default trigger 'open' state fn() { } }; const self = { state: state2, on }; function onclick(e) { e.preventDefault(); const state3 = node.classList.toggle(my.state); my.fn.call(null, state3); } function state2(s) { my.state = s; return self; } function on(fn) { my.fn = fn; return self; } if (my.trigger) { my.trigger.addEventListener("click", onclick); } return self; } // lib/client/resort/dom.js function removeAllChildren(node) { while (node.hasChildNodes()) { node.removeChild(node.lastChild); } } function next({ nextElementSibling, nextSibling }) { return nextElementSibling || nextSibling; } // lib/client/resort/lifts.js render.section = 0; render.type = "lifts"; var states = ["open", "hold", "scheduled", "closed"]; function renderStatus(node, status) { removeAllChildren(node); if (status) { node.innerHTML = Object.keys(status).map((name) => { const klass = `status ls-${status[name]}`; return `<li class="lift"><span class="name">${name}</span><span class="${klass}"></span></li>`; }).join(""); } } function renderStats(node, stats2) { states.forEach((s) => node.querySelector(`.ls-${s}`).innerHTML = stats2 ? stats2[s] : 0); } function renderColorBar(node, percentage) { states.forEach((state2) => { const width = `width:${percentage ? percentage[state2] : 25}%;`; node.querySelector(`.${state2}`).setAttribute("style", width); }); } function render(node, { status, stats: stats2 }) { renderStatus(node.querySelector(".lifts"), status); renderStats(node.querySelector(".summary"), stats2); renderColorBar(node.querySelector(".summary-color-bar"), stats2.percentage); } // lib/client/resort/snow.js var day = 24 * 60 * 60 * 1e3; render2.section = 1; render2.type = "snow"; function renderField(div, field, snow) { const el = div.querySelector(`.${field}`); const value = snow[field]; el.querySelector(".value").innerHTML = value || ""; el.classList.toggle("hidden", !value); } function render2(div, snow) { if (Date.now() - snow.timestamp > day) { return false; } renderField(div, "snowfall", snow); renderField(div, "depth", snow); renderField(div, "condition", snow); div.querySelector(".notice").innerHTML = snow.notice || ""; return true; } // lib/client/resort/weather.js var day2 = 24 * 60 * 60 * 1e3; render3.section = 1; render3.type = "weather"; function renderIcon(li, icon) { if (Array.isArray(icon)) { icon.forEach((cl, i) => li.item(i).setAttribute("class", cl)); } } function renderNotice(el, notice) { if (!notice) { return el.classList.add("hidden"); } el.classList.remove("hidden"); el = el.querySelector("a"); el.setAttribute("href", notice.href); el.setAttribute("title", `Go to ${notice.site}`); el = el.querySelector("img"); el.setAttribute("src", notice.img); el.setAttribute("style", `width:${notice.width}px;`); el.setAttribute("alt", notice.site); } function render3(div, weather) { if (Date.now() - weather.timestamp > day2) { return false; } renderIcon(div.querySelectorAll(".weather-icon > ul > li"), weather.icon); div.querySelector(".temperature").innerHTML = `${weather.temperature.max}&deg;F`; const snowforecast = div.querySelector(".snowforecast"); snowforecast.classList.toggle("hidden", !weather.snow); if (weather.snow) { snowforecast.innerHTML = `${weather.snow}"`; } div.querySelector(".conditions").innerHTML = weather.conditions; div.querySelector(".text").innerHTML = weather.text; renderNotice(div.querySelector(".notice"), weather.notice); return true; } // node_modules/.pnpm/@pirxpilot+events@3.0.0/node_modules/@pirxpilot/events/index.js function events(el, obj) { const handlers = /* @__PURE__ */ new Map(); function bind(name, handler, opts) { if (!handler) { handler = name; } if (typeof handler === "string") { handler = obj[handler].bind(obj); } el.addEventListener(name, handler, opts); handlers.set(name, { handler, opts }); } function do_unbind(name) { const h = handlers.get(name); if (h) { el.removeEventListener(name, h.handler, h.opts); handlers.delete(name); } } function unbind(name) { return name ? do_unbind(name) : unbindAll(); } function unbindAll() { handlers.forEach((h, name) => el.removeEventListener(name, h.handler, h.opts)); handlers.clear(); } return { bind, unbind }; } // node_modules/.pnpm/@pirxpilot+swipe@3.0.0/node_modules/@pirxpilot/swipe/index.js var import_component_emitter = __toESM(require_component_emitter(), 1); var _duration, _interval, _threshold, _fastThreshold; var Swipe = class extends import_component_emitter.default { constructor(el) { super(); __privateAdd(this, _duration, 300); __privateAdd(this, _interval, 5e3); __privateAdd(this, _threshold, 0.5); __privateAdd(this, _fastThreshold, 200); if (!el) throw new TypeError("Swipe() requires an element"); this.child = el.children[0]; this.touchAction("none"); this.currentEl = this.children().visible[0]; this.currentVisible = 0; this.current = 0; this.el = el; this.refresh(); this.show(0, 0, { silent: true }); this.bind(); } /** * Set the swipe threshold to `n`. * * This is the factor required for swipe * to detect when a slide has passed the * given threshold, and may display the next * or previous slide. For example the default * of `.5` means that the user must swipe _beyond_ * half of the side width. * * @param {Number} n * @api public */ threshold(n) { __privateSet(this, _threshold, n); } /** * Set the "fast" swipe threshold to `ms`. * * This is the amount of time in milliseconds * which determines if a swipe was "fast" or not. When * the swipe's duration is less than `ms` only 1/10th of * the slide's width must be exceeded to display the previous * or next slide. * * @param {Number} n * @api public */ fastThreshold(ms) { __privateSet(this, _fastThreshold, ms); } /** * Refresh sizing data. * * @api public */ refresh() { const children = this.children(); const visible2 = children.visible.length; const prev = this.visible || visible2; const i = indexOf(children.visible, this.currentEl); if (visible2 < prev && i <= this.currentVisible && i >= 0) { this.currentVisible = i; } else if (visible2 > prev && i > this.currentVisible) { this.currentVisible = i; } this.visible = visible2; this.childWidth = this.el.getBoundingClientRect().width; this.width = Math.ceil(this.childWidth * visible2); this.child.style.width = `${this.width}px`; this.child.style.height = `${this.height}px`; this.show(this.currentVisible, 0, { silent: true }); } /** * Bind event handlers. * * @api public */ bind() { this.events = events(this.child, this); this.events.bind("pointerdown", "ontouchstart"); this.events.bind("pointermove", "ontouchmove"); this.events.bind("pointerup", "ontouchend"); this.events.bind("pointercancel", "ontouchend"); } /** * Unbind event handlers. * * @api public */ unbind() { this.events.unbind(); } /** * Handle touchstart. * * @api private */ ontouchstart(e) { this.transitionDuration(0); this.dx = 0; this.updown = null; e.target.setPointerCapture(e.pointerId); this.down = { x: e.pageX, y: e.pageY, at: /* @__PURE__ */ new Date() }; } /** * Handle touchmove. * * For the first and last slides * we apply some resistence to help * indicate that you're at the edges. * * @api private */ ontouchmove(e) { if (!this.down || this.updown) return; if (!e) return; const down = this.down; const x = e.pageX; const w = this.childWidth; const i = this.currentVisible; this.dx = x - down.x; if (null == this.updown) { const y = e.pageY; const dy = y - down.y; const slope = dy / this.dx; if (slope > 1 || slope < -1) { this.updown = true; return; } this.updown = false; } e.preventDefault(); const dir = this.dx < 0 ? 1 : 0; if (this.isFirst() && 0 === dir) this.dx /= 2; if (this.isLast() && 1 === dir) this.dx /= 2; this.translate(i * w + -this.dx); } /** * Handle touchend. * * @api private */ ontouchend(e) { e.stopPropagation(); if (!this.down) return; e.target.releasePointerCapture(e.pointerId); const dx = this.dx; const w = this.childWidth; const ms = Date.now() - this.down.at; const threshold = ms < __privateGet(this, _fastThreshold) ? w / 10 : w * __privateGet(this, _threshold); const dir = dx < 0 ? 1 : 0; const half = Math.abs(dx) >= threshold; this.down = null; if (this.isFirst() && 1 === dir && half) return this.next(); if (this.isFirst()) return this.prev(); if (this.isLast() && 1 === dir) return this.next(); if (1 === dir && half) return this.next(); if (0 === dir && half) return this.prev(); this.show(this.currentVisible); } /** * Set transition duration to `ms`. * * @param {Number} ms * @return {Swipe} self * @api public */ duration(ms) { __privateSet(this, _duration, ms); return this; } /** * Set cycle interval to `ms`. * * @param {Number} ms * @return {Swipe} self * @api public */ interval(ms) { __privateSet(this, _interval, ms); return this; } /** * Play through all the elements. * * @return {Swipe} self * @api public */ play() { if (this.timer) return; this.timer = setInterval(this.cycle.bind(this), __privateGet(this, _interval)); return this; } /** * Stop playing. * * @return {Swipe} self * @api public */ stop() { clearInterval(this.timer); this.timer = null; return this; } /** * Show the next slide, when the end * is reached start from the beginning. * * @api public */ cycle() { if (this.isLast()) { this.currentVisible = -1; this.next(); } else { this.next(); } } /** * Check if we're on the first visible slide. * * @return {Boolean} * @api public */ isFirst() { return this.currentVisible === 0; } /** * Check if we're on the last visible slide. * * @return {Boolean} * @api public */ isLast() { return this.currentVisible === this.visible - 1; } /** * Show the previous slide, if any. * * @return {Swipe} self * @api public */ prev() { this.show(this.currentVisible - 1); return this; } /** * Show the next slide, if any. * * @return {Swipe} self * @api public */ next() { this.show(this.currentVisible + 1); return this; } /** * Show slide `i`. * * Emits `show `event * * @param {Number} i * @return {Swipe} self * @api public */ show(i, ms = __privateGet(this, _duration), { silent } = {}) { const children = this.children(); i = Math.max(0, Math.min(i, children.visible.length - 1)); this.currentVisible = i; this.currentEl = children.visible[i]; this.current = indexOf(children.all, this.currentEl); this.transitionDuration(ms); this.translate(this.childWidth * i); if (!silent) { this.emit("showing", this.current, this.currentEl); if (!ms) return this; this.child.addEventListener( "transitionend", () => { if (this.current === i) this.emit("show", this.current, this.currentEl); }, { once: true } ); } return this; } /** * Return children categorized by visibility. * * @return {Object} * @api private */ children() { const els = this.child.children; const ret = { all: els, visible: [], hidden: [] }; for (let i = 0; i < els.length; i++) { const el = els[i]; if (visible(el)) { ret.visible.push(el); } else { ret.hidden.push(el); } } return ret; } /** * Set transition duration. * * @api private */ transitionDuration(ms) { this.child.style.transition = `${ms}ms transform`; } /** * Translate to `x`. * * TODO: use translate component * * @api private */ translate(x) { this.child.style.transform = `translate3d(${-x}px, 0, 0)`; } /** * Sets the "touchAction" CSS style property to `value`. * * @api private */ touchAction(value) { this.child.style.touchAction = value; } }; _duration = new WeakMap(); _interval = new WeakMap(); _threshold = new WeakMap(); _fastThreshold = new WeakMap(); function indexOf(els, el) { for (let i = 0; i < els.length; i++) { if (els[i] === el) return i; } return -1; } function visible(el) { return getComputedStyle(el).display !== "none"; } // node_modules/.pnpm/tiny-pager@2.0.0/node_modules/tiny-pager/index.js var import_component_emitter2 = __toESM(require_component_emitter(), 1); // node_modules/.pnpm/el-component@2.0.3/node_modules/el-component/index.js var voids = /* @__PURE__ */ new Set([ "area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "menuitem", "meta", "param", "source", "track", "wbr" ]); function htmlTag(tag2, content, attrStr) { const text = ["<", tag2, attrStr ? ` ${attrStr}` : "", ">"]; if (!voids.has(tag2)) { text.push(content || "", "</", tag2, ">"); } return text; } function xmlTag(tag2, content, attrStr) { const text = ["<", tag2, attrStr ? ` ${attrStr}` : ""]; if (!content || !content.length) { text.push("/>"); } else { text.push(">", content, "</", tag2, ">"); } return text; } function toStr(tagFn, tagStr, content, attrs) { var _a; if (typeof content !== "string") { attrs = content; content = ""; } attrs != null ? attrs : attrs = {}; let [tag2 = "div", ...classes] = (_a = tagStr == null ? void 0 : tagStr.split(".")) != null ? _a : []; if (classes.length) { const classesStr = classes.join(" "); if (attrs["class"]) { attrs["class"] += ` ${classesStr}`; } else { attrs["class"] = classesStr; } } const ids = tag2.split("#"); if (ids.length > 1) { tag2 = ids[0] || "div"; attrs.id = ids[1]; } const attrStr = Object.entries(attrs).map(([attr, value]) => `${attr}="${value}"`).join(" "); return tagFn(tag2, content, attrStr).join(""); } var el_component_default = toStr.bind(null, htmlTag); var xml = toStr.bind(null, xmlTag); // node_modules/.pnpm/tiny-pager@2.0.0/node_modules/tiny-pager/index.js var _total, _current; var Pager = class extends import_component_emitter2.default { constructor(el) { super(); __privateAdd(this, _total, 0); __privateAdd(this, _current, 0); this.el = el; el.addEventListener("click", this.onclick.bind(this)); } total(t) { __privateSet(this, _total, t); return this; } onclick(e) { const target = e.target || e.srcElement; const page = Array.prototype.indexOf.call(this.el.children, target); if (page < 0) { return; } e.preventDefault(); e.stopPropagation(); this.select(page); } select(page, opts) { if (page === __privateGet(this, _current)) { return; } Array.prototype.forEach.call(this.el.children, (a, i) => { a.className = i === page ? "active" : "inactive"; }); __privateSet(this, _current, page); if (!(opts == null ? void 0 : opts.silent)) { this.emit("show", __privateGet(this, _current)); } return this; } render() { const html = new Array(__privateGet(this, _total)); for (let i = 0; i < __privateGet(this, _total); i++) { html[i] = el_component_default(i !== __privateGet(this, _current) ? "a.inactive" : "a.active"); } this.el.innerHTML = html.join(""); return this; } }; _total = new WeakMap(); _current = new WeakMap(); // lib/client/resort/webcams.js render4.section = 1; render4.type = "webcams"; var DELAY = 15 * 60 * 1e3; function swiper(el) { const ui = { swipe: new Swipe(el.swipe), pager: new Pager(el.pager) }; function refresh(count) { ui.swipe.refresh(); ui.pager.total(count).render(); el.pager.classList.toggle("hidden", count < 2); } function current() { return ui.swipe.currentVisible; } ui.pager.on("show", (n) => { ui.swipe.show(n, null, { silent: true }); }); ui.swipe.on("show", (n) => { ui.pager.select(n, { silent: true }); }); return { refresh, current }; } function render4(div, webcams) { let cams; let timer; let ui; function refresh() { cams.forEach((it) => { const imgs = it.node.querySelectorAll("img"); const fn = swap.bind(null, imgs, it); for (let i = 0; i < imgs.length; i++) { imgs[i].onload = fn; } imgs[it.inactive].setAttribute("src", imgs[it.active].getAttribute("src")); }); } function initCam(cam, { source, image, name, notice }) { cam.querySelector("a").setAttribute("href", source); cam.querySelector("img.active").setAttribute("src", image); cam.querySelector("img.inactive").setAttribute("src", ""); cam.querySelector(".title").innerHTML = name; cam.querySelector(".notice").innerHTML = notice || ""; cams.push({ node: cam, active: 0, inactive: 1 }); } function init3() { if (timer) { clearInterval(timer); timer = void 0; } cams = []; const ul = div.querySelector("ul"); const li = ul.querySelectorAll("li"); webcams.forEach((webcam, i) => { let cam; if (i < li.length) { cam = li[i]; } else { cam = ul.appendChild(li[0].cloneNode(true)); } initCam(cam.querySelector(".webcam"), webcam); }); for (let i = Math.max(1, webcams.length); i < li.length; i++) { ul.removeChild(li[i]); } if (!ui) { ui = swiper({ swipe: div.querySelector(".swipe"), pager: div.querySelector(".pager") }); } ui.refresh(webcams.length); if (!cams.length) { return false; } timer = setInterval(refresh, DELAY); return true; } function swap(imgs, it) { it.active = (it.active + 1) % 2; it.inactive = (it.inactive + 1) % 2; imgs[it.inactive].setAttribute("class", "inactive"); imgs[it.active].setAttribute("class", "active"); imgs[it.inactive].setAttribute("src", ""); } init3(); } // lib/client/resort/index.js function renderOpening(node, opening) { if (opening) { opening = opening.split("-"); if (new Date(opening[0], opening[1] - 1, opening[2]).getTime() <= Date.now()) { node.dataset.opening = ""; node = node.querySelector(".opening-date"); node.parentNode.removeChild(node); } } } var plugins = [render, render3, render4, render2]; function renderPlugins(node, getData) { const sec = next(node); plugins.forEach((plugin) => { const data = getData(plugin.type); if (!data) { return; } const el = plugin.section ? sec.querySelector(`.${plugin.type}`) : node; if (!el) { return; } const show = plugin(el, data); if (typeof show === "boolean") { el.classList.toggle("visible", show); el.classList.toggle("hiddent", !show); } }); } function render5(node, resort2) { const tsPrev = JSON.parse(node.dataset.timestamp); const tsCurr = resort2.timestamp; renderPlugins(node, (plugin) => { if (!resort2[plugin] || !tsCurr[plugin]) { return; } if (tsPrev[plugin] && tsCurr[plugin] <= tsPrev[plugin]) { return; } return resort2[plugin]; }); renderOpening(node, node.dataset.opening); node.dataset.timestamp = JSON.stringify(tsCurr); } var MAX = 12; function resort(node) { let updateCounter = MAX; function updateTimeToRefresh(counter) { const ttr = node.querySelector(".time-to-refresh"); ttr.innerHTML = counter * 5; } function refresh(now) { const id = node.dataset.resort; if (!node.classList.contains("open")) { return; } if (now) { updateCounter = 0; } else { updateCounter -= 1; } if (updateCounter > 0) { updateTimeToRefresh(updateCounter); return; } updateCounter = MAX; updateTimeToRefresh(updateCounter); fetch(`/api/resort/${id}`).then((res) => res.json()).then((resort2) => render5(node, resort2)); } function init3() { const ds = node.dataset; updateTimeToRefresh(MAX); renderPlugins(node, (plugin) => { const data = ds[plugin]; return data && JSON.parse(data); }); } return { init: init3, refresh, node }; } // lib/client/state/index.js var import_k = __toESM(require_lib(), 1); var k = (0, import_k.default)(window); function state(nodes, st, keys) { const cookieName = `resorts-${st}`; const self = { load, save, update, read }; function find(id) { return nodes.find((n) => n.dataset.resort === id); } function read() { const text = api.get(cookieName); return (text == null ? void 0 : text.length) ? text.split(",") : []; } function write(arr) { api.set(cookieName, arr.join(","), { expires: 30, path: "/", secure: window.location.protocol === "https:", sameSite: "strict" }); } function update() { const state2 = read().reduce((memo, id) => { memo[id] = true; return memo; }, {}); nodes.forEach(({ dataset, classList }) => { const id = dataset.resort; state2[id] = classList.contains(st); }); const selected = Object.keys(state2).filter((id) => state2[id]); write(selected); return selected; } function save() { const selected = nodes.filter((n) => n.classList.contains(st)).map((n) => n.dataset.resort); write(selected); return selected; } function load() { const selected = read(); selected.forEach((id) => { const node = find(id); if (node) { node.classList.add(st); } }); return selected; } function all(on) { nodes.forEach((n) => n.classList.toggle(st, on)); update(); } if (keys) { k(keys.on, all.bind(null, true)); k(keys.off, all.bind(null, false)); } return self; } // lib/client/stats/index.js function stats() { const pie = document.querySelector(".stats .pie"); if (!pie) { return; } const data = JSON.parse(pie.dataset.stats); let ac = 0; const { style } = pie; Object.entries(data.percentage).forEach(([key, value]) => style.setProperty(`--${key}`, `${ac += value}%`)); } // lib/client/tag/index.js function tag(node) { let count; function update(c) { if (!count) { return; } count.innerHTML = c; node.classList.toggle("hidden", c <= 0); } if (node) { count = node.querySelector(".count"); } return { update }; } // node_modules/.pnpm/debounce@3.0.0/node_modules/debounce/index.js function debounce(function_, wait = 100, options = {}) { if (typeof function_ !== "function") { throw new TypeError(`Expected the first parameter to be a function, got \`${typeof function_}\`.`); } if (wait < 0) { throw new RangeError("`wait` must not be negative."); } if (typeof options === "boolean") { throw new TypeError("The `options` parameter must be an object, not a boolean. Use `{immediate: true}` instead."); } const { immediate } = options; let storedContext; let storedArguments; let timeoutId; let timestamp; let result; function run() { const callContext = storedContext; const callArguments = storedArguments; storedContext = void 0; storedArguments = void 0; result = function_.apply(callContext, callArguments); return result; } function later() { const last = Date.now() - timestamp; if (last < wait && last >= 0) { timeoutId = setTimeout(later, wait - last); } else { timeoutId = void 0; if (!immediate) { result = run(); } } } const debounced = function(...arguments_) { if (storedContext && this !== storedContext && Object.getPrototypeOf(this) === Object.getPrototypeOf(storedContext)) { throw new Error("Debounced method called with different contexts of the same prototype."); } storedContext = this; storedArguments = arguments_; timestamp = Date.now(); const callNow = immediate && !timeoutId; if (!timeoutId) { timeoutId = setTimeout(later, wait); } if (callNow) { result = run(); return result; } return void 0; }; Object.defineProperty(debounced, "isPending", { get() { return timeoutId !== void 0; } }); debounced.clear = () => { if (!timeoutId) { return; } clearTimeout(timeoutId); timeoutId = void 0; storedContext = void 0; storedArguments = void 0; }; debounced.flush = () => { if (!timeoutId) { return; } debounced.trigger(); }; debounced.trigger = () => { result = run(); debounced.clear(); }; return debounced; } // lib/client/boot/height.js function notify() { const widget = document.querySelector(".widget"); if (!widget) { return; } window.parent.postMessage( { height: widget.scrollHeight, resort: window.location.pathname.split("/").pop() }, "*" ); } function postHeight() { if (window === window.parent) { return; } notify(); window.addEventListener("resize", debounce(notify, 300), true); } // lib/client/boot/service-worker.js function registrationHandler({ scope, installing, waiting, active }) { console.log("SW", scope); if (installing) { console.log("installing", installing.state); } if (waiting) { console.log("waiting", waiting.state); } if (active) { console.log("active", active.state); } } function register(url = "/sw.js") { if (navigator.serviceWorker && document.documentElement.hasAttribute("data-service-worker")) { return navigator.serviceWorker.register(url).then(registrationHandler).catch((reason) => console.log("SW registration failed!", reason)); } } // lib/client/boot/index.js register(); init2(); function init2() { const rnodes = Array.from(document.querySelectorAll(".resort")); const opens = state(rnodes, "open", { on: "shift + o", off: "shift + x" }); const starred = state(rnodes, "starred"); const starredTag = tag(document.querySelector(".tags .starred")); const resorts = rnodes.map((r) => resort(r)); resorts.forEach((r) => { minimax(r.node, ".minimax").state("open").on((open) => { if (open) { r.refresh(true); } opens.update(); }); minimax(r.node, ".star").state("starred").on(() => starredTag.update(starred.update().length)); r.init(); }); window.setInterval(() => resorts.forEach((r) => r.refresh()), 5 * 1e3); about(); opens.update(); starredTag.update(starred.load().length); stats(); postHeight(); } /*! Bundled license information: js-cookie/dist/js.cookie.mjs: (*! js-cookie v3.0.5 | MIT *) */ //# sourceMappingURL=liftie.js.map