UNPKG

@ideal-postcodes/jsutil

Version:

Browser Address Autocomplete for api.ideal-postcodes.co.uk

968 lines (955 loc) 27.2 kB
// lib/string.ts var isString = (input) => typeof input === "string"; var includes = (haystack, needle) => haystack.indexOf(needle) !== -1; // lib/dom.ts var hasWindow = () => typeof window !== "undefined"; var toArray = (nodeList) => Array.prototype.slice.call(nodeList); var loaded = (elem, prefix = "idpc") => elem.getAttribute(prefix) === "true"; var markLoaded = (elem, prefix = "idpc") => elem.setAttribute(prefix, "true"); var isTrue = () => true; var getParent = (node, entity, test = isTrue) => { let parent = node; const tagName = entity.toUpperCase(); while (parent.tagName !== "HTML") { if (parent.tagName === tagName && test(parent)) return parent; if (parent.parentNode === null) return null; parent = parent.parentNode; } return null; }; var toHtmlElem = (parent, selector) => selector ? parent.querySelector(selector) : null; var getAnchors = (selector, d2) => { const matches = (d2 || window.document).querySelectorAll(selector); const anchors = toArray(matches).filter((e) => !loaded(e)); if (anchors.length === 0) return []; anchors.forEach((anchor) => markLoaded(anchor)); return anchors; }; var insertBefore = ({ elem, target }) => { const parent = target.parentNode; if (parent === null) return; parent.insertBefore(elem, target); return elem; }; var toElem = (elem, context) => { if (isString(elem)) return context.querySelector(elem); return elem; }; var d = () => window.document; var getScope = (scope) => { if (isString(scope)) return d().querySelector(scope); if (scope === null) return d(); return scope; }; var getDocument = (scope) => { if (scope instanceof Document || scope.constructor.name === "HTMLDocument") return scope; if (scope.ownerDocument) return scope.ownerDocument; return d(); }; var setStyle = (element, style) => { const currentRules = element.getAttribute("style"); Object.keys(style).forEach( (key) => element.style[key] = style[key] ); return currentRules; }; var restoreStyle = (element, style) => { element.setAttribute("style", style || ""); }; var hide = (e) => { e.style.display = "none"; return e; }; var show = (e) => { e.style.display = ""; return e; }; var remove = (elem) => { if (elem === null || elem.parentNode === null) return; elem.parentNode.removeChild(elem); }; var contains = (scope, selector, text) => { const elements = scope.querySelectorAll(selector); for (let i = 0; i < elements.length; i++) { const e = elements[i]; const content = e.innerText; if (content && content.trim() === text) return e; } return null; }; var findCommonParent = (elements) => { if (elements.length < 1) return null; if (elements.length === 1) return elements[0].parentElement || elements[0]; const getPathToRoot = (element) => { const path = []; let current = element; while (current) { path.push(current); current = current.parentElement; } return path.reverse(); }; const paths = elements.map(getPathToRoot); const minLength = Math.min(...paths.map((path) => path.length)); let commonAncestor = null; for (let depth = 0; depth < minLength; depth++) { const currentNode = paths[0][depth]; if (paths.every((path) => path[depth] === currentNode)) { commonAncestor = currentNode; } else { break; } } return commonAncestor; }; // lib/util.ts var getTargets = (parent, selectors) => { const line_1 = toHtmlElem(parent, selectors.line_1); if (line_1 === null) return null; const post_town = toHtmlElem(parent, selectors.post_town); if (post_town === null) return null; const postcode = parent.querySelector(selectors.postcode); if (postcode === null) return null; const line_2 = toHtmlElem(parent, selectors.line_2); const line_3 = toHtmlElem(parent, selectors.line_3); const country = toHtmlElem(parent, selectors.country); const county = toHtmlElem(parent, selectors.county); const organisation = toHtmlElem( parent, selectors.organisation ); return { line_1, line_2, line_3, post_town, county, postcode, organisation, country }; }; var relevantPage = (bindings) => bindings.some((b) => b.pageTest()); var defaults = { enabled: true, apiKey: "", populateCounty: false, // Autocomplete config autocomplete: true, autocompleteOverride: {}, // Postcode lookup config postcodeLookup: true, postcodeLookupOverride: {} }; var config = () => { const c = window.idpcConfig; if (c === void 0) return; return { ...defaults, ...c }; }; var generateTimer = ({ pageTest, bind, interval = 1e3 }) => { let timer = null; const start = (config2) => { if (!pageTest()) return null; timer = window.setInterval(() => { try { bind(config2); } catch (e) { stop(); console.log(e); } }, interval); return timer; }; const stop = () => { if (timer === null) return; window.clearInterval(timer); timer = null; }; return { start, stop }; }; var NOOP = () => { }; var setup = ({ bindings, callback = NOOP }) => { const c = config(); if (c === void 0) return callback(); if (!relevantPage(bindings)) return callback(); const result = bindings.reduce((prev, binding) => { const { pageTest, bind } = binding; if (!pageTest()) return prev; const { start, stop } = generateTimer({ pageTest, bind }); start(c); prev.push({ binding, start, stop }); return prev; }, []); return callback(result); }; var DEFAULT_SCOPE = "form"; var DEFAULT_ANCHOR = "line_1"; var setupBind = ({ selectors, anchorSelector, parentScope, doc, parentTest }) => { const anchors = getAnchors(anchorSelector || selectors[DEFAULT_ANCHOR], doc); return anchors.reduce((prev, anchor) => { const parent = getParent(anchor, parentScope || DEFAULT_SCOPE, parentTest); if (!parent) return prev; const targets = getTargets(parent, selectors); if (targets === null) return prev; prev.push({ targets, parent, anchor }); return prev; }, []); }; var toId = (elem) => `#${elem.id}`; var cssEscape = (value) => { value = String(value); const length = value.length; let index = -1; let codeUnit; let result = ""; const firstCodeUnit = value.charCodeAt(0); while (++index < length) { codeUnit = value.charCodeAt(index); if (codeUnit == 0) { result += "\uFFFD"; continue; } if (codeUnit >= 1 && codeUnit <= 31 || codeUnit == 127 || index == 0 && codeUnit >= 48 && codeUnit <= 57 || index == 1 && codeUnit >= 48 && codeUnit <= 57 && firstCodeUnit == 45) { result += "\\" + codeUnit.toString(16) + " "; continue; } if (index == 0 && length == 1 && codeUnit == 45) { result += "\\" + value.charAt(index); continue; } if (codeUnit >= 128 || codeUnit == 45 || codeUnit == 95 || codeUnit >= 48 && codeUnit <= 57 || codeUnit >= 65 && codeUnit <= 90 || codeUnit >= 97 && codeUnit <= 122) { result += value.charAt(index); continue; } result += "\\" + value.charAt(index); } return result; }; // lib/types.ts var isGbrAddress = (address) => ( //@ts-ignore address.post_town !== void 0 ); // lib/assets.ts var cache = {}; var clearCache = () => { for (const url of Object.keys(cache)) { delete cache[url]; } }; var downloadScript = (url, integrity) => (d2) => { if (cache[url]) return cache[url]; const document2 = d2 || window.document; const script = loadScript(url, integrity, document2); document2.head.appendChild(script); cache[url] = script; return script; }; var loadStyle = (href, document2) => { const link = document2.createElement("link"); link.type = "text/css"; link.rel = "stylesheet"; link.href = href; return link; }; var loadScript = (src, integrity, document2) => { const script = document2.createElement("script"); script.type = "text/javascript"; script.crossOrigin = "anonymous"; script.integrity = integrity; script.src = src; return script; }; var injectStyle = (css, document2) => { const style = document2.createElement("style"); style.appendChild(document2.createTextNode(css)); document2.head.appendChild(style); return style; }; // lib/event.ts var newEvent = ({ event, bubbles = true, cancelable = true }) => { if (typeof window.Event === "function") return new window.Event(event, { bubbles, cancelable }); const e = document.createEvent("Event"); e.initEvent(event, bubbles, cancelable); return e; }; var trigger = (e, event) => e.dispatchEvent(newEvent({ event })); // lib/input.ts var isSelect = (e) => { if (e === null) return false; return e instanceof HTMLSelectElement || e.constructor.name === "HTMLSelectElement"; }; var isInput = (e) => { if (e === null) return false; return e instanceof HTMLInputElement || e.constructor.name === "HTMLInputElement"; }; var isTextarea = (e) => { if (e === null) return false; return e instanceof HTMLTextAreaElement || e.constructor.name === "HTMLTextAreaElement"; }; var isInputElem = (e) => isInput(e) || isTextarea(e) || isSelect(e); var update = (input, value, skipTrigger = false) => { if (!input) return; if (!isInput(input) && !isTextarea(input)) return; change({ e: input, value, skipTrigger }); }; var hasValue = (select, value) => { if (value === null) return false; return select.querySelector(`[value="${value}"]`) !== null; }; var optionsHasText = (select, value) => { if (value === null) return []; const options = select.querySelectorAll("option"); return Array.from(options).filter((o) => { const normalizedText = o.textContent ? o.textContent.replace(/[\n\r]/g, "").replace(/\s+/g, " ").trim() : ""; return normalizedText === value; }); }; var updateSelect = ({ e, value, skipTrigger }) => { if (value === null) return; if (!isSelect(e)) return; setValue(e, value); if (!skipTrigger) trigger(e, "select"); trigger(e, "change"); }; var setValue = (e, value) => { const descriptor = Object.getOwnPropertyDescriptor( e.constructor.prototype, "value" ); if (descriptor === void 0) return; if (descriptor.set === void 0) return; const setter = descriptor.set; setter.call(e, value); }; var updateInput = ({ e, value, skipTrigger }) => { if (value === null) return; if (!isInput(e) && !isTextarea(e)) return; setValue(e, value); if (!skipTrigger) trigger(e, "input"); trigger(e, "change"); }; var change = (options) => { if (options.value === null) return; updateSelect(options); updateInput(options); }; // lib/country.ts var UK = "United Kingdom"; var IOM = "Isle of Man"; var EN = "England"; var SC = "Scotland"; var WA = "Wales"; var NI = "Northern Ireland"; var CI = "Channel Islands"; var toCountry = (address) => { const country = address.country; if (country === EN) return UK; if (country === SC) return UK; if (country === WA) return UK; if (country === NI) return UK; if (country === IOM) return IOM; if (isGbrAddress(address)) { if (country === CI) { if (/^GY/.test(address.postcode)) return "Guernsey"; if (/^JE/.test(address.postcode)) return "Jersey"; } } return country; }; var updateCountry = (select, address) => { if (!select) return; if (isSelect(select)) { const bcc = toCountry(address); if (hasValue(select, bcc)) { change({ e: select, value: bcc }); return; } if (hasValue(select, address.country_iso_2)) { change({ e: select, value: address.country_iso_2 }); return; } if (hasValue(select, address.country_iso)) { change({ e: select, value: address.country_iso }); return; } let text = optionsHasText(select, bcc); if (text.length > 0) { change({ e: select, value: text[0].value || "" }); return; } text = optionsHasText(select, address.country_iso_2); if (text.length > 0) { change({ e: select, value: text[0].value || "" }); return; } text = optionsHasText(select, address.country_iso); if (text.length > 0) { change({ e: select, value: text[0].value || "" }); return; } } if (isInput(select)) { const bcc = toCountry(address); change({ e: select, value: bcc }); } }; // lib/store.ts var g = {}; if (hasWindow()) { if (window.idpcGlobal) { g = window.idpcGlobal; } else { window.idpcGlobal = g; } } var idpcState = () => g; var reset = () => Object.getOwnPropertyNames(g).forEach((p) => delete g[p]); // lib/id.ts var idGen = (prefix = "idpc_") => () => { const g2 = idpcState(); if (!g2.idGen) g2.idGen = {}; if (g2.idGen[prefix] === void 0) g2.idGen[prefix] = 0; g2.idGen[prefix] += 1; return `${prefix}${g2.idGen[prefix]}`; }; // lib/address.ts var numberOfLines = (targets) => { const { line_2, line_3 } = targets; if (!line_2) return 1; if (!line_3) return 2; return 3; }; var join = (list) => list.filter((e) => { if (isString(e)) return !!e.trim(); return !!e; }).join(", "); var charArrayLength = (arr) => arr.join(" ").trim().length; var truncate = (line, maxLength) => { if (line.length <= maxLength) return [line, ""]; const words = line.split(" "); let truncated = ""; let remaining = ""; for (let i = 0; i < words.length; i++) { const word = words[i]; if (truncated.length + word.length > maxLength) { remaining = words.slice(i).join(" "); break; } truncated += `${word} `; } return [truncated.trim(), remaining.trim()]; }; var prependLine = (remaining, nextLine) => { if (nextLine.length === 0) return remaining; return `${remaining}, ${nextLine}`; }; var toMaxLengthLines = (l, options) => { const { lineCount, maxLineOne, maxLineTwo, maxLineThree } = options; const result = ["", "", ""]; const lines = [...l]; if (maxLineOne) { const [newLineOne, remaining] = truncate(lines[0], maxLineOne); result[0] = newLineOne; if (remaining) lines[1] = prependLine(remaining, lines[1]); if (lineCount === 1) return result; } else { result[0] = lines[0]; if (lineCount === 1) return [join(lines), "", ""]; } if (maxLineTwo) { const [newLineTwo, remaining] = truncate(lines[1], maxLineTwo); result[1] = newLineTwo; if (remaining) lines[2] = prependLine(remaining, lines[2]); if (lineCount === 2) return result; } else { result[1] = lines[1]; if (lineCount === 2) return [result[0], join(lines.slice(1)), ""]; } if (maxLineThree) { const [newLineThree, remaining] = truncate(lines[2], maxLineThree); result[2] = newLineThree; if (remaining) lines[3] = prependLine(remaining, lines[3]); } else { result[2] = lines[2]; } return result; }; var toAddressLines = (lineCount, address, options) => { const { line_1, line_2 } = address; const line_3 = "line_3" in address ? address.line_3 : ""; if (options.maxLineOne || options.maxLineTwo || options.maxLineThree) return toMaxLengthLines([line_1, line_2, line_3], { lineCount, ...options }); if (lineCount === 3) return [line_1, line_2, line_3]; if (lineCount === 2) return [line_1, join([line_2, line_3]), ""]; return [join([line_1, line_2, line_3]), "", ""]; }; var extract = (a, attr) => { const result = a[attr]; if (typeof result === "number") return result.toString(); if (result === void 0) return ""; return result; }; var getFields = (o) => ({ ...searchFields(o.outputFields || {}, o.config.scope), ...searchNames(o.names || {}, o.config.scope), ...searchLabels(o.labels || {}, o.config.scope) }); var searchFields = (outputFields, scope) => { const fields = {}; let key; for (key in outputFields) { const value = outputFields[key]; if (value === void 0) continue; const field = toElem(value, scope); if (isInputElem(field)) fields[key] = field; } return fields; }; var searchNames = (names, scope) => { const result = {}; let key; for (key in names) { if (!names.hasOwnProperty(key)) continue; const name = names[key]; const named = toElem(`[name="${name}"]`, scope); if (named) { result[key] = named; continue; } const ariaNamed = toElem(`[aria-name="${name}"]`, scope); if (ariaNamed) result[key] = ariaNamed; } return result; }; var searchLabels = (labels, scope) => { const result = {}; if (labels === void 0) return labels; let key; for (key in labels) { if (!labels.hasOwnProperty(key)) continue; const name = labels[key]; if (!name) continue; const first = contains(scope, "label", name); const label = toElem(first, scope); if (!label) continue; const forEl = label.getAttribute("for"); if (forEl) { const byId = scope.querySelector(`#${cssEscape(forEl)}`); if (byId) { result[key] = byId; continue; } } const inner = label.querySelector("input"); if (inner) result[key] = inner; } return result; }; var skipFields = ["country", "country_iso_2", "country_iso"]; var mutateAddress = (address, config2) => { if (isGbrAddress(address)) { if (config2.removeOrganisation) removeOrganisation(address); } const [line_1, line_2, line_3] = toAddressLines( config2.lines || 3, address, config2 ); address.line_1 = line_1; address.line_2 = line_2; if (isGbrAddress(address)) address.line_3 = line_3; return address; }; var populateAddress = (options) => { const { config: config2 } = options; const fields = getFields(options); if (config2.lines === void 0) config2.lines = numberOfLines(fields); const address = mutateAddress({ ...options.address }, config2); const { scope, populateCounty } = config2; const skip = [...skipFields]; if (isGbrAddress(address)) { if (config2.removeOrganisation) removeOrganisation(address); if (populateCounty === false) skip.push("county"); } updateCountry(toElem(fields.country || null, scope), address); const iso2Elem = toElem(fields.country_iso_2 || null, scope); if (isSelect(iso2Elem)) { if (hasValue(iso2Elem, address.country_iso_2)) { change({ e: iso2Elem, value: address.country_iso_2 }); } else { let text = optionsHasText(iso2Elem, address.country_iso_2); if (text.length > 0) { change({ e: iso2Elem, value: text[0].value || "" }); } else { text = optionsHasText(iso2Elem, toCountry(address)); if (text.length > 0) { change({ e: iso2Elem, value: text[0].value || "" }); } } } } if (isInput(iso2Elem)) { update(iso2Elem, address.country_iso_2 || ""); } const iso3Elem = toElem(fields.country_iso || null, scope); if (isSelect(iso3Elem)) { if (hasValue(iso3Elem, address.country_iso)) { change({ e: iso3Elem, value: address.country_iso }); } else { let text = optionsHasText(iso3Elem, address.country_iso); if (text.length > 0) { change({ e: iso3Elem, value: text[0].value || "" }); } else { text = optionsHasText(iso3Elem, toCountry(address)); if (text.length > 0) { change({ e: iso3Elem, value: text[0].value || "" }); } } } } if (isInput(iso3Elem)) update(iso3Elem, address.country_iso || ""); const countyIso = toElem(getCountyIsoSelector(fields), scope); const countyIsoValue = getCountyIso(address); const countyValue = getCounty(address); if (isSelect(countyIso)) { if (hasValue(countyIso, countyIsoValue)) { change({ e: countyIso, value: countyIsoValue }); } else if (hasValue(countyIso, countyValue || "")) { change({ e: countyIso, value: countyValue || "" }); } else { let text = optionsHasText(countyIso, countyValue); if (text.length > 0) { change({ e: countyIso, value: text[0].value || "" }); } else { text = optionsHasText(countyIso, countyIsoValue); if (text) change({ e: countyIso, value: text[0].value || "" }); } } } if (isInput(countyIso)) { update(countyIso, countyIsoValue); } let e; for (e in fields) { if (skip.includes(e)) continue; if (e.startsWith("native.")) { updateNative(e, fields, address, scope); continue; } if (address[e] === void 0) continue; if (fields.hasOwnProperty(e)) { const value = fields[e]; if (!value) continue; update(toElem(value, scope), extract(address, e)); } } }; var updateNative = (nativeAttr, fields, address, scope) => { const e = nativeAttr.replace("native.", ""); const native = address.native; if (native === void 0) return; const nativeValue = native[e]; if (nativeValue === void 0) return; if (fields.hasOwnProperty(nativeAttr)) { const selector = fields[nativeAttr]; if (!selector) return; update(toElem(selector, scope), extract(native, e)); } }; var removeOrganisation = (address) => { if (address.organisation_name.length === 0) return address; if (address.line_2.length === 0 && address.line_3.length === 0) return address; if (address.line_1 === address.organisation_name) { address.line_1 = address.line_2; address.line_2 = address.line_3; address.line_3 = ""; } return address; }; var isUsaOutputFields = (a) => a.hasOwnProperty("state_abbreviation"); var getCountyIsoSelector = (a) => { if (isUsaOutputFields(a)) return a.state_abbreviation || null; return a.county_code || null; }; var getCountySelector = (a) => { if (isUsaOutputFields(a)) return a.state || null; return a.county || null; }; var getCountyIso = (a) => { if (isGbrAddress(a)) return a.county_code; return a.state_abbreviation; }; var getCounty = (a) => { if (isGbrAddress(a)) return a.county; return a.state; }; // lib/keyboard.ts var keyCodeMapping = { 13: "Enter", 38: "ArrowUp", 40: "ArrowDown", 36: "Home", 35: "End", 27: "Escape", 8: "Backspace" }; var supportedKeys = [ "Enter", "ArrowUp", "ArrowDown", "Home", "End", "Escape", "Backspace" ]; var supported = (k) => supportedKeys.indexOf(k) !== -1; var toKey = (event) => { if (event.keyCode) return keyCodeMapping[event.keyCode] || null; return supported(event.key) ? event.key : null; }; // lib/debounce.ts var isObject = (value) => { var type = typeof value; return !!value && (type == "object" || type == "function"); }; var debounce = function(func, wait, options) { let lastArgs, lastThis, maxWait, result, timerId, lastCallTime; let lastInvokeTime = 0; let leading = false; let maxing = false; let trailing = true; if (typeof func !== "function") { throw new TypeError("Expected a function"); } wait = +wait || 0; if (isObject(options)) { leading = !!options.leading; maxing = "maxWait" in options; maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait; trailing = "trailing" in options ? !!options.trailing : trailing; } function invokeFunc(time) { const args = lastArgs; const thisArg = lastThis; lastArgs = lastThis = void 0; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { lastInvokeTime = time; timerId = setTimeout(timerExpired, wait); return leading ? invokeFunc(time) : result; } function remainingWait(time) { const timeSinceLastCall = time - lastCallTime; const timeSinceLastInvoke = time - lastInvokeTime; const timeWaiting = wait - timeSinceLastCall; return maxing ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; } function shouldInvoke(time) { const timeSinceLastCall = time - lastCallTime; const timeSinceLastInvoke = time - lastInvokeTime; return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; } function timerExpired() { const time = Date.now(); if (shouldInvoke(time)) { return trailingEdge(time); } timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = void 0; if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = void 0; return result; } function cancel() { if (timerId !== void 0) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = void 0; } function pending() { return timerId !== void 0; } function debounced(...args) { const time = Date.now(); const isInvoking = shouldInvoke(time); lastArgs = args; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === void 0) { return leadingEdge(lastCallTime); } if (maxing) { timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === void 0) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.pending = pending; return debounced; }; // lib/watcher.ts var watchTimer = ({ bind, interval = 1e3 }) => { let timer = null; const start = () => { timer = window.setInterval(() => { try { bind(); } catch (e) { stop(); } }, interval); return timer; }; const stop = () => { if (timer === null) return; window.clearInterval(timer); timer = null; }; return { start, stop }; }; var watchMutation = ({ bind, interval = 1e3, target = window.document, observerConfig = { subtree: true, childList: true } }) => { const observer = new MutationObserver( debounce(() => { try { bind(); } catch (e) { stop(); } }, interval) ); const start = () => { observer.observe(target, observerConfig); return null; }; const stop = () => observer.disconnect(); return { start, stop }; }; var watchChange = (options) => { if (!window) return watchTimer(options); if (!window.MutationObserver) return watchTimer(options); if (options.mutationObserver) return watchMutation(options); return watchTimer(options); }; export { change, charArrayLength, clearCache, config, contains, cssEscape, debounce, defaults, downloadScript, extract, findCommonParent, generateTimer, getAnchors, getCounty, getCountyIso, getCountyIsoSelector, getCountySelector, getDocument, getFields, getParent, getScope, getTargets, hasValue, hasWindow, hide, idGen, idpcState, includes, injectStyle, insertBefore, isGbrAddress, isInput, isInputElem, isObject, isSelect, isString, isTextarea, join, keyCodeMapping, loadScript, loadStyle, loaded, markLoaded, mutateAddress, newEvent, numberOfLines, optionsHasText, populateAddress, relevantPage, remove, removeOrganisation, reset, restoreStyle, searchFields, searchLabels, searchNames, setStyle, setValue, setup, setupBind, show, supportedKeys, toAddressLines, toArray, toCountry, toElem, toHtmlElem, toId, toKey, toMaxLengthLines, trigger, update, updateCountry, watchChange, watchMutation, watchTimer }; //# sourceMappingURL=index.mjs.map