{"version":3,"file":"off-webcomponents.bundled.cjs","sources":["../src/localization/dist/locale-codes.ts","../node_modules/signal-polyfill/dist/index.js","../node_modules/@lit-labs/signals/lib/signal-watcher.js","../node_modules/lit-html/directive.js","../node_modules/lit-html/directive-helpers.js","../node_modules/lit-html/async-directive.js","../node_modules/@lit-labs/signals/index.js","../src/constants.ts","../src/signals/app.ts","../src/localization/index.ts","../src/utils/signals.ts","../src/signals/robotoff.ts","../src/signals/folksonomy.ts","../node_modules/@lit/reactive-element/decorators/custom-element.js","../node_modules/@lit/reactive-element/decorators/property.js","../node_modules/@lit/reactive-element/decorators/state.js","../node_modules/@lit/reactive-element/decorators/base.js","../node_modules/@lit/reactive-element/decorators/query.js","../src/utils/index.ts","../src/api/openfoodfacts.ts","../src/signals/openfoodfacts.ts","../src/components/shared/off-webcomponents-configuration.ts","../src/types/robotoff.ts","../node_modules/openapi-fetch/dist/index.mjs","../node_modules/@openfoodfacts/openfoodfacts-nodejs/dist/esm/version.js","../node_modules/@openfoodfacts/openfoodfacts-nodejs/dist/esm/consts.js","../node_modules/@openfoodfacts/openfoodfacts-nodejs/dist/esm/formbody.js","../node_modules/@openfoodfacts/openfoodfacts-nodejs/dist/esm/robotoff.js","../node_modules/@openfoodfacts/openfoodfacts-nodejs/dist/esm/taxonomy/api.js","../node_modules/@openfoodfacts/openfoodfacts-nodejs/dist/esm/openapi.js","../node_modules/@openfoodfacts/openfoodfacts-nodejs/dist/esm/off-v2.js","../node_modules/@openfoodfacts/openfoodfacts-nodejs/dist/esm/off-v3.js","../node_modules/@openfoodfacts/openfoodfacts-nodejs/dist/esm/off.js","../src/api/robotoff.ts","../src/signals/questions.ts","../node_modules/@lit/task/task.js","../src/components/shared/loader.ts","../src/utils/colors.ts","../src/styles/buttons.ts","../src/mixins/loading-with-timeout-mixin.ts","../src/styles/utils.ts","../src/components/icons/loading-spin.ts","../src/components/shared/loading-button.ts","../src/components/icons/zoom.ts","../src/components/icons/unzoom.ts","../src/components/buttons/zoom-unzoom-button.ts","../node_modules/lit-html/directives/style-map.js","../src/components/icons/rotate-left.ts","../src/components/icons/rotate-right.ts","../src/utils/breakpoints.ts","../node_modules/@cropper/utils/dist/utils.esm.raw.js","../node_modules/@cropper/element/dist/element.esm.raw.js","../node_modules/@cropper/element-canvas/dist/element-canvas.esm.raw.js","../node_modules/@cropper/element-image/dist/element-image.esm.raw.js","../node_modules/@cropper/element-handle/dist/element-handle.esm.raw.js","../node_modules/@cropper/element-selection/dist/element-selection.esm.raw.js","../node_modules/@cropper/element-crosshair/dist/element-crosshair.esm.raw.js","../node_modules/@cropper/element-shade/dist/element-shade.esm.raw.js","../src/components/icons/arrows-center.ts","../src/styles/form.ts","../src/styles/alert.ts","../src/mixins/message-display-mixin.ts","../src/components/shared/zoomable-image.ts","../src/components/robotoff-question/robotoff-question-form.ts","../src/styles/base.ts","../src/components/robotoff-question/robotoff-question.ts","../src/signals/nutrient-extraction.ts","../src/api/taxonomies.ts","../src/signals/taxonomies.ts","../src/utils/nutrient-extraction.ts","../src/directives/background-image.ts","../src/styles/folksonomy-input.ts","../node_modules/lit-html/directives/class-map.js","../src/components/shared/autocomplete-input.ts","../src/components/icons/suggestion.ts","../src/components/icons/add.ts","../src/components/icons/eye-visible.ts","../src/components/icons/eye-invisible.ts","../src/components/robotoff-nutrient-extraction/robotoff-nutrient-extraction-form.ts","../src/utils/openfoodfacts.ts","../node_modules/lit-html/directives/if-defined.js","../src/mixins/language-codes-mixin.ts","../src/mixins/country-codes-mixin.ts","../src/components/icons/external-link.ts","../src/components/shared/product-link-button.ts","../src/mixins/display-product-link-mixin.ts","../src/components/robotoff-nutrient-extraction/robotoff-nutrient-extraction.ts","../src/signals/ingredient-spellcheck.ts","../src/components/icons/check.ts","../src/components/icons/cross.ts","../src/components/icons/skip.ts","../src/components/icons/edit.ts","../src/components/icons/info.ts","../src/components/shared/info-button.ts","../src/styles/popover.ts","../src/styles/text-corrector.ts","../src/directives/click-outside.ts","../src/types/ingredient-spellcheck.ts","../node_modules/lit-html/directives/unsafe-html.js","../node_modules/dompurify/dist/purify.es.mjs","../src/utils/html.ts","../node_modules/diff/libesm/diff/base.js","../node_modules/diff/libesm/diff/word.js","../src/mixins/text-diff-mixin.ts","../src/utils/knowledge-panels/heading-utils.ts","../src/components/shared/text-corrector-highlight.ts","../src/components/robotoff-ingredient-spellcheck/text-corrector.ts","../src/components/robotoff-ingredient-spellcheck/robotoff-ingredient-spellcheck.ts","../src/styles/responsive.ts","../src/styles/modal.ts","../src/components/shared/modal.ts","../src/signals/ingredient-detection.ts","../src/utils/crop.ts","../src/components/robotoff-ingredient-detection/robotoff-ingredient-detection-form.ts","../src/components/robotoff-ingredient-detection/robotoff-ingredient-detection.ts","../src/components/robotoff-modal/robotoff-modal.ts","../src/components/robotoff-contribution-message/robotoff-contribution-message.ts","../src/api/knowledgepanel.ts","../src/components/knowledge-panels/renderers/render-action.ts","../src/components/knowledge-panels/renderers/render-text.ts","../src/components/knowledge-panels/renderers/render-table.ts","../src/components/knowledge-panels/renderers/render-titled-text.ts","../src/utils/knowledge-panels/extract-images.ts","../src/components/knowledge-panels/renderers/render-panel-header.ts","../src/components/knowledge-panels/renderers/render-image.ts","../src/components/knowledge-panels/renderers/render-panel.ts","../src/components/knowledge-panels/renderers/render-panel-element.ts","../src/components/knowledge-panels/renderers/render-panel-group.ts","../src/components/knowledge-panels/renderers/render-element.ts","../src/components/knowledge-panels/knowledge-panels.ts","../src/utils/dark-mode-listener.ts","../src/components/donation-banner/donation-banner.ts","../src/components/mobile-badges/mobile-badges.ts","../src/components/download-app-qr-code/download-app-qr-code.ts","../src/components/icons/barcode.ts","../src/components/icons/search.ts","../src/components/icons/close.ts","../src/mixins/console-log-mixin.ts","../src/components/barcode-scanner/barcode-scanner.ts","../src/components/folksonomy/delete-modal.ts","../src/components/folksonomy/new-key-modal.ts","../src/api/folksonomy.ts","../src/components/folksonomy/folksonomy-editor-row.ts","../src/components/folksonomy/folksonomy-editor.ts","../src/components/shared/dual-range-slider.ts","../src/components/folksonomy/folksonomy-properties.ts","../src/components/folksonomy/folksonomy-property-products.ts","../src/components/product-card/product-card.ts","../node_modules/marked/lib/marked.esm.js","../node_modules/dayjs/esm/constant.js","../node_modules/dayjs/esm/locale/en.js","../node_modules/dayjs/esm/utils.js","../node_modules/dayjs/esm/index.js","../src/components/news-feed/news-feed.ts","../src/off-webcomponents.ts"],"sourcesContent":["// Do not modify this file by hand!\n// Re-generate this file by running lit-localize.\n\n/**\n * The locale code that templates in this source code are written in.\n */\nexport const sourceLocale = `en`;\n\n/**\n * The other locale codes that this application is localized into. Sorted\n * lexicographically.\n */\nexport const targetLocales = [\n  `af`,\n  `am`,\n  `ar`,\n  `ay`,\n  `az`,\n  `be`,\n  `bg`,\n  `bi`,\n  `bn`,\n  `bs`,\n  `ca`,\n  `ch`,\n  `cs`,\n  `cy`,\n  `da`,\n  `de`,\n  `dv`,\n  `dz`,\n  `el`,\n  `en`,\n  `es`,\n  `et`,\n  `eu`,\n  `fa`,\n  `fi`,\n  `fj`,\n  `fr`,\n  `ga`,\n  `gd`,\n  `gl`,\n  `gn`,\n  `gv`,\n  `he`,\n  `hi`,\n  `ho`,\n  `hr`,\n  `ht`,\n  `hu`,\n  `hy`,\n  `id`,\n  `is`,\n  `it`,\n  `ja`,\n  `ka`,\n  `kk`,\n  `kl`,\n  `km`,\n  `ko`,\n  `ku`,\n  `ky`,\n  `la`,\n  `lb`,\n  `lo`,\n  `lt`,\n  `lv`,\n  `mg`,\n  `mh`,\n  `mi`,\n  `mk`,\n  `mn`,\n  `ms`,\n  `mt`,\n  `my`,\n  `na`,\n  `nb`,\n  `nd`,\n  `ne`,\n  `nl`,\n  `nr`,\n  `ny`,\n  `pap`,\n  `pl`,\n  `prs`,\n  `ps`,\n  `pt`,\n  `qu`,\n  `rn`,\n  `ro`,\n  `ru`,\n  `rw`,\n  `sg`,\n  `si`,\n  `sk`,\n  `sl`,\n  `sm`,\n  `sn`,\n  `so`,\n  `sq`,\n  `sr`,\n  `ss`,\n  `st`,\n  `sv`,\n  `sw`,\n  `ta`,\n  `tg`,\n  `th`,\n  `ti`,\n  `tk`,\n  `tl`,\n  `tn`,\n  `to`,\n  `tr`,\n  `ts`,\n  `uk`,\n  `ur`,\n  `uz`,\n  `ve`,\n  `vi`,\n  `xh`,\n  `zh`,\n  `zu`,\n] as const;\n\n/**\n * All valid project locale codes. Sorted lexicographically.\n */\nexport const allLocales = [\n  `af`,\n  `am`,\n  `ar`,\n  `ay`,\n  `az`,\n  `be`,\n  `bg`,\n  `bi`,\n  `bn`,\n  `bs`,\n  `ca`,\n  `ch`,\n  `cs`,\n  `cy`,\n  `da`,\n  `de`,\n  `dv`,\n  `dz`,\n  `el`,\n  `en`,\n  `en`,\n  `es`,\n  `et`,\n  `eu`,\n  `fa`,\n  `fi`,\n  `fj`,\n  `fr`,\n  `ga`,\n  `gd`,\n  `gl`,\n  `gn`,\n  `gv`,\n  `he`,\n  `hi`,\n  `ho`,\n  `hr`,\n  `ht`,\n  `hu`,\n  `hy`,\n  `id`,\n  `is`,\n  `it`,\n  `ja`,\n  `ka`,\n  `kk`,\n  `kl`,\n  `km`,\n  `ko`,\n  `ku`,\n  `ky`,\n  `la`,\n  `lb`,\n  `lo`,\n  `lt`,\n  `lv`,\n  `mg`,\n  `mh`,\n  `mi`,\n  `mk`,\n  `mn`,\n  `ms`,\n  `mt`,\n  `my`,\n  `na`,\n  `nb`,\n  `nd`,\n  `ne`,\n  `nl`,\n  `nr`,\n  `ny`,\n  `pap`,\n  `pl`,\n  `prs`,\n  `ps`,\n  `pt`,\n  `qu`,\n  `rn`,\n  `ro`,\n  `ru`,\n  `rw`,\n  `sg`,\n  `si`,\n  `sk`,\n  `sl`,\n  `sm`,\n  `sn`,\n  `so`,\n  `sq`,\n  `sr`,\n  `ss`,\n  `st`,\n  `sv`,\n  `sw`,\n  `ta`,\n  `tg`,\n  `th`,\n  `ti`,\n  `tk`,\n  `tl`,\n  `tn`,\n  `to`,\n  `tr`,\n  `ts`,\n  `uk`,\n  `ur`,\n  `uz`,\n  `ve`,\n  `vi`,\n  `xh`,\n  `zh`,\n  `zu`,\n] as const;\n","var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => {\n  __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n  return value;\n};\nvar __accessCheck = (obj, member, msg) => {\n  if (!member.has(obj))\n    throw TypeError(\"Cannot \" + msg);\n};\nvar __privateIn = (member, obj) => {\n  if (Object(obj) !== obj)\n    throw TypeError('Cannot use the \"in\" operator on this value');\n  return member.has(obj);\n};\nvar __privateAdd = (obj, member, value) => {\n  if (member.has(obj))\n    throw TypeError(\"Cannot add the same private member more than once\");\n  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\n};\nvar __privateMethod = (obj, member, method) => {\n  __accessCheck(obj, member, \"access private method\");\n  return method;\n};\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nfunction defaultEquals(a, b) {\n  return Object.is(a, b);\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nlet activeConsumer = null;\nlet inNotificationPhase = false;\nlet epoch = 1;\nconst SIGNAL = /* @__PURE__ */ Symbol(\"SIGNAL\");\nfunction setActiveConsumer(consumer) {\n  const prev = activeConsumer;\n  activeConsumer = consumer;\n  return prev;\n}\nfunction getActiveConsumer() {\n  return activeConsumer;\n}\nfunction isInNotificationPhase() {\n  return inNotificationPhase;\n}\nconst REACTIVE_NODE = {\n  version: 0,\n  lastCleanEpoch: 0,\n  dirty: false,\n  producerNode: void 0,\n  producerLastReadVersion: void 0,\n  producerIndexOfThis: void 0,\n  nextProducerIndex: 0,\n  liveConsumerNode: void 0,\n  liveConsumerIndexOfThis: void 0,\n  consumerAllowSignalWrites: false,\n  consumerIsAlwaysLive: false,\n  producerMustRecompute: () => false,\n  producerRecomputeValue: () => {\n  },\n  consumerMarkedDirty: () => {\n  },\n  consumerOnSignalRead: () => {\n  }\n};\nfunction producerAccessed(node) {\n  if (inNotificationPhase) {\n    throw new Error(\n      typeof ngDevMode !== \"undefined\" && ngDevMode ? `Assertion error: signal read during notification phase` : \"\"\n    );\n  }\n  if (activeConsumer === null) {\n    return;\n  }\n  activeConsumer.consumerOnSignalRead(node);\n  const idx = activeConsumer.nextProducerIndex++;\n  assertConsumerNode(activeConsumer);\n  if (idx < activeConsumer.producerNode.length && activeConsumer.producerNode[idx] !== node) {\n    if (consumerIsLive(activeConsumer)) {\n      const staleProducer = activeConsumer.producerNode[idx];\n      producerRemoveLiveConsumerAtIndex(staleProducer, activeConsumer.producerIndexOfThis[idx]);\n    }\n  }\n  if (activeConsumer.producerNode[idx] !== node) {\n    activeConsumer.producerNode[idx] = node;\n    activeConsumer.producerIndexOfThis[idx] = consumerIsLive(activeConsumer) ? producerAddLiveConsumer(node, activeConsumer, idx) : 0;\n  }\n  activeConsumer.producerLastReadVersion[idx] = node.version;\n}\nfunction producerIncrementEpoch() {\n  epoch++;\n}\nfunction producerUpdateValueVersion(node) {\n  if (!node.dirty && node.lastCleanEpoch === epoch) {\n    return;\n  }\n  if (!node.producerMustRecompute(node) && !consumerPollProducersForChange(node)) {\n    node.dirty = false;\n    node.lastCleanEpoch = epoch;\n    return;\n  }\n  node.producerRecomputeValue(node);\n  node.dirty = false;\n  node.lastCleanEpoch = epoch;\n}\nfunction producerNotifyConsumers(node) {\n  if (node.liveConsumerNode === void 0) {\n    return;\n  }\n  const prev = inNotificationPhase;\n  inNotificationPhase = true;\n  try {\n    for (const consumer of node.liveConsumerNode) {\n      if (!consumer.dirty) {\n        consumerMarkDirty(consumer);\n      }\n    }\n  } finally {\n    inNotificationPhase = prev;\n  }\n}\nfunction producerUpdatesAllowed() {\n  return (activeConsumer == null ? void 0 : activeConsumer.consumerAllowSignalWrites) !== false;\n}\nfunction consumerMarkDirty(node) {\n  var _a;\n  node.dirty = true;\n  producerNotifyConsumers(node);\n  (_a = node.consumerMarkedDirty) == null ? void 0 : _a.call(node.wrapper ?? node);\n}\nfunction consumerBeforeComputation(node) {\n  node && (node.nextProducerIndex = 0);\n  return setActiveConsumer(node);\n}\nfunction consumerAfterComputation(node, prevConsumer) {\n  setActiveConsumer(prevConsumer);\n  if (!node || node.producerNode === void 0 || node.producerIndexOfThis === void 0 || node.producerLastReadVersion === void 0) {\n    return;\n  }\n  if (consumerIsLive(node)) {\n    for (let i = node.nextProducerIndex; i < node.producerNode.length; i++) {\n      producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);\n    }\n  }\n  while (node.producerNode.length > node.nextProducerIndex) {\n    node.producerNode.pop();\n    node.producerLastReadVersion.pop();\n    node.producerIndexOfThis.pop();\n  }\n}\nfunction consumerPollProducersForChange(node) {\n  assertConsumerNode(node);\n  for (let i = 0; i < node.producerNode.length; i++) {\n    const producer = node.producerNode[i];\n    const seenVersion = node.producerLastReadVersion[i];\n    if (seenVersion !== producer.version) {\n      return true;\n    }\n    producerUpdateValueVersion(producer);\n    if (seenVersion !== producer.version) {\n      return true;\n    }\n  }\n  return false;\n}\nfunction producerAddLiveConsumer(node, consumer, indexOfThis) {\n  var _a;\n  assertProducerNode(node);\n  assertConsumerNode(node);\n  if (node.liveConsumerNode.length === 0) {\n    (_a = node.watched) == null ? void 0 : _a.call(node.wrapper);\n    for (let i = 0; i < node.producerNode.length; i++) {\n      node.producerIndexOfThis[i] = producerAddLiveConsumer(node.producerNode[i], node, i);\n    }\n  }\n  node.liveConsumerIndexOfThis.push(indexOfThis);\n  return node.liveConsumerNode.push(consumer) - 1;\n}\nfunction producerRemoveLiveConsumerAtIndex(node, idx) {\n  var _a;\n  assertProducerNode(node);\n  assertConsumerNode(node);\n  if (typeof ngDevMode !== \"undefined\" && ngDevMode && idx >= node.liveConsumerNode.length) {\n    throw new Error(\n      `Assertion error: active consumer index ${idx} is out of bounds of ${node.liveConsumerNode.length} consumers)`\n    );\n  }\n  if (node.liveConsumerNode.length === 1) {\n    (_a = node.unwatched) == null ? void 0 : _a.call(node.wrapper);\n    for (let i = 0; i < node.producerNode.length; i++) {\n      producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);\n    }\n  }\n  const lastIdx = node.liveConsumerNode.length - 1;\n  node.liveConsumerNode[idx] = node.liveConsumerNode[lastIdx];\n  node.liveConsumerIndexOfThis[idx] = node.liveConsumerIndexOfThis[lastIdx];\n  node.liveConsumerNode.length--;\n  node.liveConsumerIndexOfThis.length--;\n  if (idx < node.liveConsumerNode.length) {\n    const idxProducer = node.liveConsumerIndexOfThis[idx];\n    const consumer = node.liveConsumerNode[idx];\n    assertConsumerNode(consumer);\n    consumer.producerIndexOfThis[idxProducer] = idx;\n  }\n}\nfunction consumerIsLive(node) {\n  var _a;\n  return node.consumerIsAlwaysLive || (((_a = node == null ? void 0 : node.liveConsumerNode) == null ? void 0 : _a.length) ?? 0) > 0;\n}\nfunction assertConsumerNode(node) {\n  node.producerNode ?? (node.producerNode = []);\n  node.producerIndexOfThis ?? (node.producerIndexOfThis = []);\n  node.producerLastReadVersion ?? (node.producerLastReadVersion = []);\n}\nfunction assertProducerNode(node) {\n  node.liveConsumerNode ?? (node.liveConsumerNode = []);\n  node.liveConsumerIndexOfThis ?? (node.liveConsumerIndexOfThis = []);\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nfunction computedGet(node) {\n  producerUpdateValueVersion(node);\n  producerAccessed(node);\n  if (node.value === ERRORED) {\n    throw node.error;\n  }\n  return node.value;\n}\nfunction createComputed(computation) {\n  const node = Object.create(COMPUTED_NODE);\n  node.computation = computation;\n  const computed = () => computedGet(node);\n  computed[SIGNAL] = node;\n  return computed;\n}\nconst UNSET = /* @__PURE__ */ Symbol(\"UNSET\");\nconst COMPUTING = /* @__PURE__ */ Symbol(\"COMPUTING\");\nconst ERRORED = /* @__PURE__ */ Symbol(\"ERRORED\");\nconst COMPUTED_NODE = /* @__PURE__ */ (() => {\n  return {\n    ...REACTIVE_NODE,\n    value: UNSET,\n    dirty: true,\n    error: null,\n    equal: defaultEquals,\n    producerMustRecompute(node) {\n      return node.value === UNSET || node.value === COMPUTING;\n    },\n    producerRecomputeValue(node) {\n      if (node.value === COMPUTING) {\n        throw new Error(\"Detected cycle in computations.\");\n      }\n      const oldValue = node.value;\n      node.value = COMPUTING;\n      const prevConsumer = consumerBeforeComputation(node);\n      let newValue;\n      let wasEqual = false;\n      try {\n        newValue = node.computation.call(node.wrapper);\n        const oldOk = oldValue !== UNSET && oldValue !== ERRORED;\n        wasEqual = oldOk && node.equal.call(node.wrapper, oldValue, newValue);\n      } catch (err) {\n        newValue = ERRORED;\n        node.error = err;\n      } finally {\n        consumerAfterComputation(node, prevConsumer);\n      }\n      if (wasEqual) {\n        node.value = oldValue;\n        return;\n      }\n      node.value = newValue;\n      node.version++;\n    }\n  };\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nfunction defaultThrowError() {\n  throw new Error();\n}\nlet throwInvalidWriteToSignalErrorFn = defaultThrowError;\nfunction throwInvalidWriteToSignalError() {\n  throwInvalidWriteToSignalErrorFn();\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nfunction createSignal(initialValue) {\n  const node = Object.create(SIGNAL_NODE);\n  node.value = initialValue;\n  const getter = () => {\n    producerAccessed(node);\n    return node.value;\n  };\n  getter[SIGNAL] = node;\n  return getter;\n}\nfunction signalGetFn() {\n  producerAccessed(this);\n  return this.value;\n}\nfunction signalSetFn(node, newValue) {\n  if (!producerUpdatesAllowed()) {\n    throwInvalidWriteToSignalError();\n  }\n  if (!node.equal.call(node.wrapper, node.value, newValue)) {\n    node.value = newValue;\n    signalValueChanged(node);\n  }\n}\nconst SIGNAL_NODE = /* @__PURE__ */ (() => {\n  return {\n    ...REACTIVE_NODE,\n    equal: defaultEquals,\n    value: void 0\n  };\n})();\nfunction signalValueChanged(node) {\n  node.version++;\n  producerIncrementEpoch();\n  producerNotifyConsumers(node);\n}\n/**\n * @license\n * Copyright 2024 Bloomberg Finance L.P.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst NODE = Symbol(\"node\");\nvar Signal;\n((Signal2) => {\n  var _a, _brand, brand_fn, _b, _brand2, brand_fn2;\n  class State {\n    constructor(initialValue, options = {}) {\n      __privateAdd(this, _brand);\n      __publicField(this, _a);\n      const ref = createSignal(initialValue);\n      const node = ref[SIGNAL];\n      this[NODE] = node;\n      node.wrapper = this;\n      if (options) {\n        const equals = options.equals;\n        if (equals) {\n          node.equal = equals;\n        }\n        node.watched = options[Signal2.subtle.watched];\n        node.unwatched = options[Signal2.subtle.unwatched];\n      }\n    }\n    get() {\n      if (!(0, Signal2.isState)(this))\n        throw new TypeError(\"Wrong receiver type for Signal.State.prototype.get\");\n      return signalGetFn.call(this[NODE]);\n    }\n    set(newValue) {\n      if (!(0, Signal2.isState)(this))\n        throw new TypeError(\"Wrong receiver type for Signal.State.prototype.set\");\n      if (isInNotificationPhase()) {\n        throw new Error(\"Writes to signals not permitted during Watcher callback\");\n      }\n      const ref = this[NODE];\n      signalSetFn(ref, newValue);\n    }\n  }\n  _a = NODE;\n  _brand = new WeakSet();\n  brand_fn = function() {\n  };\n  Signal2.isState = (s) => typeof s === \"object\" && __privateIn(_brand, s);\n  Signal2.State = State;\n  class Computed {\n    // Create a Signal which evaluates to the value returned by the callback.\n    // Callback is called with this signal as the parameter.\n    constructor(computation, options) {\n      __privateAdd(this, _brand2);\n      __publicField(this, _b);\n      const ref = createComputed(computation);\n      const node = ref[SIGNAL];\n      node.consumerAllowSignalWrites = true;\n      this[NODE] = node;\n      node.wrapper = this;\n      if (options) {\n        const equals = options.equals;\n        if (equals) {\n          node.equal = equals;\n        }\n        node.watched = options[Signal2.subtle.watched];\n        node.unwatched = options[Signal2.subtle.unwatched];\n      }\n    }\n    get() {\n      if (!(0, Signal2.isComputed)(this))\n        throw new TypeError(\"Wrong receiver type for Signal.Computed.prototype.get\");\n      return computedGet(this[NODE]);\n    }\n  }\n  _b = NODE;\n  _brand2 = new WeakSet();\n  brand_fn2 = function() {\n  };\n  Signal2.isComputed = (c) => typeof c === \"object\" && __privateIn(_brand2, c);\n  Signal2.Computed = Computed;\n  ((subtle2) => {\n    var _a2, _brand3, brand_fn3, _assertSignals, assertSignals_fn;\n    function untrack(cb) {\n      let output;\n      let prevActiveConsumer = null;\n      try {\n        prevActiveConsumer = setActiveConsumer(null);\n        output = cb();\n      } finally {\n        setActiveConsumer(prevActiveConsumer);\n      }\n      return output;\n    }\n    subtle2.untrack = untrack;\n    function introspectSources(sink) {\n      var _a3;\n      if (!(0, Signal2.isComputed)(sink) && !(0, Signal2.isWatcher)(sink)) {\n        throw new TypeError(\"Called introspectSources without a Computed or Watcher argument\");\n      }\n      return ((_a3 = sink[NODE].producerNode) == null ? void 0 : _a3.map((n) => n.wrapper)) ?? [];\n    }\n    subtle2.introspectSources = introspectSources;\n    function introspectSinks(signal) {\n      var _a3;\n      if (!(0, Signal2.isComputed)(signal) && !(0, Signal2.isState)(signal)) {\n        throw new TypeError(\"Called introspectSinks without a Signal argument\");\n      }\n      return ((_a3 = signal[NODE].liveConsumerNode) == null ? void 0 : _a3.map((n) => n.wrapper)) ?? [];\n    }\n    subtle2.introspectSinks = introspectSinks;\n    function hasSinks(signal) {\n      if (!(0, Signal2.isComputed)(signal) && !(0, Signal2.isState)(signal)) {\n        throw new TypeError(\"Called hasSinks without a Signal argument\");\n      }\n      const liveConsumerNode = signal[NODE].liveConsumerNode;\n      if (!liveConsumerNode)\n        return false;\n      return liveConsumerNode.length > 0;\n    }\n    subtle2.hasSinks = hasSinks;\n    function hasSources(signal) {\n      if (!(0, Signal2.isComputed)(signal) && !(0, Signal2.isWatcher)(signal)) {\n        throw new TypeError(\"Called hasSources without a Computed or Watcher argument\");\n      }\n      const producerNode = signal[NODE].producerNode;\n      if (!producerNode)\n        return false;\n      return producerNode.length > 0;\n    }\n    subtle2.hasSources = hasSources;\n    class Watcher {\n      // When a (recursive) source of Watcher is written to, call this callback,\n      // if it hasn't already been called since the last `watch` call.\n      // No signals may be read or written during the notify.\n      constructor(notify) {\n        __privateAdd(this, _brand3);\n        __privateAdd(this, _assertSignals);\n        __publicField(this, _a2);\n        let node = Object.create(REACTIVE_NODE);\n        node.wrapper = this;\n        node.consumerMarkedDirty = notify;\n        node.consumerIsAlwaysLive = true;\n        node.consumerAllowSignalWrites = false;\n        node.producerNode = [];\n        this[NODE] = node;\n      }\n      // Add these signals to the Watcher's set, and set the watcher to run its\n      // notify callback next time any signal in the set (or one of its dependencies) changes.\n      // Can be called with no arguments just to reset the \"notified\" state, so that\n      // the notify callback will be invoked again.\n      watch(...signals) {\n        if (!(0, Signal2.isWatcher)(this)) {\n          throw new TypeError(\"Called unwatch without Watcher receiver\");\n        }\n        __privateMethod(this, _assertSignals, assertSignals_fn).call(this, signals);\n        const node = this[NODE];\n        node.dirty = false;\n        const prev = setActiveConsumer(node);\n        for (const signal of signals) {\n          producerAccessed(signal[NODE]);\n        }\n        setActiveConsumer(prev);\n      }\n      // Remove these signals from the watched set (e.g., for an effect which is disposed)\n      unwatch(...signals) {\n        if (!(0, Signal2.isWatcher)(this)) {\n          throw new TypeError(\"Called unwatch without Watcher receiver\");\n        }\n        __privateMethod(this, _assertSignals, assertSignals_fn).call(this, signals);\n        const node = this[NODE];\n        assertConsumerNode(node);\n        for (let i = node.producerNode.length - 1; i >= 0; i--) {\n          if (signals.includes(node.producerNode[i].wrapper)) {\n            producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);\n            const lastIdx = node.producerNode.length - 1;\n            node.producerNode[i] = node.producerNode[lastIdx];\n            node.producerIndexOfThis[i] = node.producerIndexOfThis[lastIdx];\n            node.producerNode.length--;\n            node.producerIndexOfThis.length--;\n            node.nextProducerIndex--;\n            if (i < node.producerNode.length) {\n              const idxConsumer = node.producerIndexOfThis[i];\n              const producer = node.producerNode[i];\n              assertProducerNode(producer);\n              producer.liveConsumerIndexOfThis[idxConsumer] = i;\n            }\n          }\n        }\n      }\n      // Returns the set of computeds in the Watcher's set which are still yet\n      // to be re-evaluated\n      getPending() {\n        if (!(0, Signal2.isWatcher)(this)) {\n          throw new TypeError(\"Called getPending without Watcher receiver\");\n        }\n        const node = this[NODE];\n        return node.producerNode.filter((n) => n.dirty).map((n) => n.wrapper);\n      }\n    }\n    _a2 = NODE;\n    _brand3 = new WeakSet();\n    brand_fn3 = function() {\n    };\n    _assertSignals = new WeakSet();\n    assertSignals_fn = function(signals) {\n      for (const signal of signals) {\n        if (!(0, Signal2.isComputed)(signal) && !(0, Signal2.isState)(signal)) {\n          throw new TypeError(\"Called watch/unwatch without a Computed or State argument\");\n        }\n      }\n    };\n    Signal2.isWatcher = (w) => __privateIn(_brand3, w);\n    subtle2.Watcher = Watcher;\n    function currentComputed() {\n      var _a3;\n      return (_a3 = getActiveConsumer()) == null ? void 0 : _a3.wrapper;\n    }\n    subtle2.currentComputed = currentComputed;\n    subtle2.watched = Symbol(\"watched\");\n    subtle2.unwatched = Symbol(\"unwatched\");\n  })(Signal2.subtle || (Signal2.subtle = {}));\n})(Signal || (Signal = {}));\nexport {\n  Signal\n};\n","import{Signal as t}from\"signal-polyfill\";\n/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const i=Symbol(\"SignalWatcherBrand\"),s=new FinalizationRegistry((({watcher:t,signal:i})=>{t.unwatch(i)})),h=new WeakMap;function e(e){return!0===e[i]?(console.warn(\"SignalWatcher should not be applied to the same class more than once.\"),e):class extends e{constructor(){super(...arguments),this._$St=new t.State(0),this._$Si=!1,this._$So=!0,this._$Sh=new Set}_$Sl(){if(void 0!==this._$Su)return;this._$Sv=new t.Computed((()=>{this._$St.get(),super.performUpdate()}));const i=this._$Su=new t.subtle.Watcher((function(){const t=h.get(this);void 0!==t&&(!1===t._$Si&&t.requestUpdate(),this.watch())}));h.set(i,this),s.register(this,{watcher:i,signal:this._$Sv}),i.watch(this._$Sv)}_$Sp(){void 0!==this._$Su&&(this._$Su.unwatch(this._$Sv),this._$Sv=void 0,this._$Su=void 0)}performUpdate(){this.isUpdatePending&&(this._$Sl(),this._$Si=!0,this._$St.set(this._$St.get()+1),this._$Si=!1,this._$Sv.get())}update(t){try{this._$So?(this._$So=!1,super.update(t)):this._$Sh.forEach((t=>t.commit()))}finally{this.isUpdatePending=!1,this._$Sh.clear()}}requestUpdate(t,i,s){this._$So=!0,super.requestUpdate(t,i,s)}connectedCallback(){super.connectedCallback(),this.requestUpdate()}disconnectedCallback(){super.disconnectedCallback(),queueMicrotask((()=>{!1===this.isConnected&&this._$Sp()}))}_(t){this._$Sh.add(t);const i=this._$So;this.requestUpdate(),this._$So=i}m(t){this._$Sh.delete(t)}}}export{e as SignalWatcher};\n//# sourceMappingURL=signal-watcher.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e=t=>(...e)=>({_$litDirective$:t,values:e});class i{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}export{i as Directive,t as PartType,e as directive};\n//# sourceMappingURL=directive.js.map\n","import{_$LH as o}from\"./lit-html.js\";\n/**\n * @license\n * Copyright 2020 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const{I:t}=o,i=o=>null===o||\"object\"!=typeof o&&\"function\"!=typeof o,n={HTML:1,SVG:2,MATHML:3},e=(o,t)=>void 0===t?void 0!==o?._$litType$:o?._$litType$===t,l=o=>null!=o?._$litType$?.h,d=o=>void 0!==o?._$litDirective$,c=o=>o?._$litDirective$,f=o=>void 0===o.strings,r=()=>document.createComment(\"\"),s=(o,i,n)=>{const e=o._$AA.parentNode,l=void 0===i?o._$AB:i._$AA;if(void 0===n){const i=e.insertBefore(r(),l),d=e.insertBefore(r(),l);n=new t(i,d,o,o.options)}else{const t=n._$AB.nextSibling,i=n._$AM,d=i!==o;if(d){let t;n._$AQ?.(o),n._$AM=o,void 0!==n._$AP&&(t=o._$AU)!==i._$AU&&n._$AP(t)}if(t!==l||d){let o=n._$AA;for(;o!==t;){const t=o.nextSibling;e.insertBefore(o,l),o=t}}}return n},v=(o,t,i=o)=>(o._$AI(t,i),o),u={},m=(o,t=u)=>o._$AH=t,p=o=>o._$AH,M=o=>{o._$AR(),o._$AA.remove()},h=o=>{o._$AR()};export{n as TemplateResultType,h as clearPart,p as getCommittedValue,c as getDirectiveClass,s as insertPart,l as isCompiledTemplateResult,d as isDirectiveResult,i as isPrimitive,f as isSingleExpression,e as isTemplateResult,M as removePart,v as setChildPartValue,m as setCommittedValue};\n//# sourceMappingURL=directive-helpers.js.map\n","import{isSingleExpression as i}from\"./directive-helpers.js\";import{Directive as t,PartType as e}from\"./directive.js\";export{directive}from\"./directive.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const s=(i,t)=>{const e=i._$AN;if(void 0===e)return!1;for(const i of e)i._$AO?.(t,!1),s(i,t);return!0},o=i=>{let t,e;do{if(void 0===(t=i._$AM))break;e=t._$AN,e.delete(i),i=t}while(0===e?.size)},r=i=>{for(let t;t=i._$AM;i=t){let e=t._$AN;if(void 0===e)t._$AN=e=new Set;else if(e.has(i))break;e.add(i),c(t)}};function h(i){void 0!==this._$AN?(o(this),this._$AM=i,r(this)):this._$AM=i}function n(i,t=!1,e=0){const r=this._$AH,h=this._$AN;if(void 0!==h&&0!==h.size)if(t)if(Array.isArray(r))for(let i=e;i<r.length;i++)s(r[i],!1),o(r[i]);else null!=r&&(s(r,!1),o(r));else s(this,i)}const c=i=>{i.type==e.CHILD&&(i._$AP??=n,i._$AQ??=h)};class f extends t{constructor(){super(...arguments),this._$AN=void 0}_$AT(i,t,e){super._$AT(i,t,e),r(this),this.isConnected=i._$AU}_$AO(i,t=!0){i!==this.isConnected&&(this.isConnected=i,i?this.reconnected?.():this.disconnected?.()),t&&(s(this,i),o(this))}setValue(t){if(i(this._$Ct))this._$Ct._$AI(t,this);else{const i=[...this._$Ct._$AH];i[this._$Ci]=t,this._$Ct._$AI(i,this,0)}}disconnected(){}reconnected(){}}export{f as AsyncDirective,t as Directive,e as PartType};\n//# sourceMappingURL=async-directive.js.map\n","import{Signal as t}from\"signal-polyfill\";export*from\"signal-polyfill\";export{SignalWatcher}from\"./lib/signal-watcher.js\";export{WatchDirective,watch}from\"./lib/watch.js\";export{html,svg,withWatch}from\"./lib/html-tag.js\";\n/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const l=t.State,o=t.Computed,r=(l,o)=>new t.State(l,o),i=(l,o)=>new t.Computed(l,o);export{o as Computed,l as State,i as computed,r as signal};\n//# sourceMappingURL=index.js.map\n","export const DEFAULT_ROBOTOFF_CONFIGURATION = {\n  apiUrl: \"https://robotoff.openfoodfacts.org/api/v1\",\n  dryRun: false,\n  imgUrl: \"https://images.openfoodfacts.org/images/products\",\n}\n\nexport const DEFAULT_FOLKSONOMY_CONFIGURATION = {\n  apiUrl: \"https://api.folksonomy.openfoodfacts.org\",\n}\n\nexport const PAGE_SIZE = 25\n\nexport enum EventType {\n  CLOSE = \"close\",\n  SUCCESS = \"success\",\n  SAVE = \"save\",\n  SUBMIT = \"submit\",\n  REFUSE = \"refuse\",\n  SKIP = \"skip\",\n  QUESTION_STATE = \"question-state\",\n  NUTRIENT_STATE = \"nutrient-state\",\n  BARCODE_SCANNER_STATE = \"barcode-scanner-state\",\n  INGREDIENT_SPELLCHECK_STATE = \"ingredient-spellcheck-state\",\n  INGREDIENT_DETECTION_STATE = \"ingredient-detection-state\",\n  INPUT = \"INPUT\",\n}\n\nexport enum LoadingState {\n  NOT_LOADED = \"not-loaded\",\n  LOADING = \"loading\",\n  LOADED = \"loaded\",\n}\n\nexport const DEFAULT_LANGUAGE_CODE = \"en\"\nexport const DEFAULT_COUNTRY_CODE = \"fr\"\n\nexport enum EventState {\n  LOADING = \"loading\", // loading data\n  NO_DATA = \"no-data\", // no data to display\n  HAS_DATA = \"has-data\", // data to display\n  ANNOTATED = \"annotated\", // user do one annotation\n  FINISHED = \"FINISHED\", // user do all annotations\n}\n\nexport const DEFAULT_ASSETS_IMAGES_PATH = \"/assets/images\"\n\nexport const SELECT_ICON_FILE_NAME = \"carret-bottom.svg\"\nexport const WHITE_SELECT_ICON_FILE_NAME = \"white-carret-bottom.svg\"\n\nexport enum RobotoffContributionType {\n  QUESTIONS = \"questions\",\n  INGREDIENT_SPELLCHECK = \"ingredient_spellcheck\",\n  NUTRIENT_EXTRACTION = \"nutrient_extraction\",\n  INGREDIENT_DETECTION = \"ingredient_detection\",\n}\n\nexport const STATIC_HOST = \"https://static.openfoodfacts.org\"\n","import { signal } from \"@lit-labs/signals\"\nimport {\n  DEFAULT_ASSETS_IMAGES_PATH,\n  DEFAULT_COUNTRY_CODE,\n  DEFAULT_LANGUAGE_CODE,\n} from \"../constants\"\n\nexport const assetsImagesPath = signal(DEFAULT_ASSETS_IMAGES_PATH)\n\nexport const getImageUrl = (fileName: string) => {\n  return `${assetsImagesPath.get()}/${fileName}`\n}\n\nexport const countryCode = signal(DEFAULT_COUNTRY_CODE)\n\n/**\n * The language code of the app.\n * We add it instead of using getLocale because it is not reactive and it have a delay.\n * The delay can create double task fetch with the old and the new language code.\n */\nexport const languageCode = signal(DEFAULT_LANGUAGE_CODE)\n","import { configureLocalization } from \"@lit/localize\"\nimport { sourceLocale, targetLocales } from \"./dist/locale-codes\"\nimport { languageCode } from \"../signals/app\"\n\n/**\n * Configure the localization, it will load the locale files and set the source and target locales\n */\nexport const { getLocale, setLocale } = configureLocalization({\n  sourceLocale,\n  targetLocales,\n  loadLocale: (locale: string) => import(`./dist/locales/${locale}.ts`),\n})\n\nexport const setLanguageCode = (newLanguageCode: string) => {\n  if (!(targetLocales as readonly string[]).includes(newLanguageCode)) {\n    throw new Error(`Invalid language code: ${newLanguageCode}`)\n  }\n  // Set the language code (en, fr, ..)\n  setLocale(newLanguageCode)\n  languageCode.set(newLanguageCode)\n}\n","// Set signal object state attribute\n\nimport { Signal, State } from \"@lit-labs/signals\"\n\nexport type SignalMapType<T> = Record<string, T>\n\nexport class SignalObject<T extends Record<string, any>> extends State<T> {\n  constructor(initialValue: T, options: Signal.Options<T> = {}) {\n    super(initialValue, options)\n  }\n\n  getItem(key: string): T[keyof T] {\n    return super.get()[key]\n  }\n\n  setItem(key: string, value: T[keyof T]) {\n    super.set({ ...super.get(), [key]: value })\n  }\n}\n\nexport class SignalMap<T> extends SignalObject<SignalMapType<T>> {}\n","import { DEFAULT_ROBOTOFF_CONFIGURATION } from \"../constants\"\nimport type { RobotoffConfigurationOptions } from \"../types/robotoff\"\nimport { SignalObject } from \"../utils/signals\"\n\n/**\n * Configuration for the robotoff web components\n */\nexport const robotoffConfiguration = new SignalObject<RobotoffConfigurationOptions>({\n  ...DEFAULT_ROBOTOFF_CONFIGURATION,\n})\n\nexport const getRobotoffImageUrl = (path: string) =>\n  `${robotoffConfiguration.getItem(\"imgUrl\")}${path}`\n","import { DEFAULT_FOLKSONOMY_CONFIGURATION } from \"../constants\"\nimport type { FolksonomyConfigurationOptions, UserInfo } from \"../types/folksonomy\"\nimport { SignalObject } from \"../utils/signals\"\nimport { State } from \"@lit-labs/signals\"\n\n/**\n * Configuration for the folksonomy web components\n */\nexport const folksonomyConfiguration = new SignalObject<FolksonomyConfigurationOptions>({\n  ...DEFAULT_FOLKSONOMY_CONFIGURATION,\n})\n\n/**\n * Shared user info signal\n */\nexport const userInfo = new State<UserInfo | null>(null)\n\n/**\n * Loading state for user info\n */\nexport const userInfoLoading = new State<boolean>(false)\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=t=>(e,o)=>{void 0!==o?o.addInitializer((()=>{customElements.define(t,e)})):customElements.define(t,e)};export{t as customElement};\n//# sourceMappingURL=custom-element.js.map\n","import{defaultConverter as t,notEqual as e}from\"../reactive-element.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o={attribute:!0,type:String,converter:t,reflect:!1,hasChanged:e},r=(t=o,e,r)=>{const{kind:n,metadata:i}=r;let s=globalThis.litPropertyMetadata.get(i);if(void 0===s&&globalThis.litPropertyMetadata.set(i,s=new Map),\"setter\"===n&&((t=Object.create(t)).wrapped=!0),s.set(r.name,t),\"accessor\"===n){const{name:o}=r;return{set(r){const n=e.get.call(this);e.set.call(this,r),this.requestUpdate(o,n,t)},init(e){return void 0!==e&&this.C(o,void 0,t,e),e}}}if(\"setter\"===n){const{name:o}=r;return function(r){const n=this[o];e.call(this,r),this.requestUpdate(o,n,t)}}throw Error(\"Unsupported decorator location: \"+n)};function n(t){return(e,o)=>\"object\"==typeof o?r(t,e,o):((t,e,o)=>{const r=e.hasOwnProperty(o);return e.constructor.createProperty(o,t),r?Object.getOwnPropertyDescriptor(e,o):void 0})(t,e,o)}export{n as property,r as standardProperty};\n//# sourceMappingURL=property.js.map\n","import{property as t}from\"./property.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */function r(r){return t({...r,state:!0,attribute:!1})}export{r as state};\n//# sourceMappingURL=state.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst e=(e,t,c)=>(c.configurable=!0,c.enumerable=!0,Reflect.decorate&&\"object\"!=typeof t&&Object.defineProperty(e,t,c),c);export{e as desc};\n//# sourceMappingURL=base.js.map\n","import{desc as t}from\"./base.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */function e(e,r){return(n,s,i)=>{const o=t=>t.renderRoot?.querySelector(e)??null;if(r){const{get:e,set:r}=\"object\"==typeof s?n:i??(()=>{const t=Symbol();return{get(){return this[t]},set(e){this[t]=e}}})();return t(n,s,{get(){let t=e.call(this);return void 0===t&&(t=o(this),(null!==t||this.hasUpdated)&&r.call(this,t)),t}})}return t(n,s,{get(){return o(this)}})}}export{e as query};\n//# sourceMappingURL=query.js.map\n","/**\n * Converts a value to a string.\n * If the value is an array, it will be joined with a comma.\n * If the value is an object, it will be stringified with JSON.stringify\n * If the value is null or undefined, it will return an empty string.\n * @param value\n * @returns string - the string representation of the value\n */\nexport const paramToString = (value: any): string => {\n  if (isNullOrUndefined(value)) {\n    return \"\"\n  }\n  if (Array.isArray(value)) {\n    return value.map((item) => encodeURIComponent(item)).join(\",\")\n  }\n  if (typeof value === \"object\") {\n    value = JSON.stringify(value)\n  } else {\n    value = value.toString()\n  }\n  return encodeURIComponent(value)\n}\n\n/**\n * Converts a record of params to a URLSearchParams string.\n * @param params\n * @returns string - the URLSearchParams string\n */\nexport const paramsToUrl = (params: Record<string, any>) => {\n  const paramsToStringRecord = Object.entries(params).reduce((acc, [key, value]) => {\n    if (acc) {\n      acc += \"&\"\n    }\n    acc += `${key}=${paramToString(value)}`\n    return acc\n  }, \"\")\n  return paramsToStringRecord\n}\n\n/**\n * Adds params to a URL.\n * If the URL already has params, it will append the new params with an &.\n * @param url\n * @param params\n * @returns string - the url with the params appended\n */\nexport const addParamsToUrl = (url: string, params: Record<string, any>) => {\n  if (url.includes(\"?\")) {\n    return `${url}&${paramsToUrl(params)}`\n  }\n  return `${url}?${paramsToUrl(params)}`\n}\n\n// Function to delay the execution of a function\nexport const delay = (ms: number) => new Promise((res) => setTimeout(res, ms))\n\n/**\n * Checks if a value is null or undefined.\n * @param value\n * @returns boolean - true if the value is null or undefined, false otherwise\n */\nexport const isNullOrUndefined = (value: any) => value === null || value === undefined\n\n/**\n * Given a key with dot inside representing nested objects,\n * create inner object and set value on leaf node\n *\n * @example: setValueAndParentsObjectIfNotExists({}, \"a.b.c\", 3) will create {a: {b: {c: 3}}}\n */\nexport const setValueAndParentsObjectIfNotExists = (\n  obj: Record<string, any>,\n  key: string,\n  value: any\n) => {\n  const keys = key.split(\".\")\n  const lastKey = keys.pop() as string\n  let lastObject: Record<string, any> = {}\n\n  keys.reduce((acc, key) => {\n    if (!acc[key]) {\n      acc[key] = {}\n    }\n    lastObject = acc[key]\n    return acc[key]\n  }, obj)\n\n  lastObject[lastKey] = value\n  return obj\n}\n\n/**\n * Generates a random ID.\n * @returns string - a random ID\n */\nexport const randomIdGenerator = () => Math.random().toString(36).substring(2, 15)\n\n/**\n * Initializes a debounce function.\n * @param callback - the function to debounce\n * @returns () => void - the debounced function\n */\nexport const initDebounce = (callback: () => any, debounceTime: number = 500) => {\n  let timeout: number | undefined\n  return () => {\n    clearTimeout(timeout)\n    timeout = setTimeout(() => {\n      callback()\n    }, debounceTime)\n  }\n}\n\n/**\n * Creates a debounce utility that can be used with class methods\n * @param debounceTime - the delay in milliseconds\n * @returns object with debounce method and clear method\n */\nexport const createDebounce = (debounceTime: number = 500) => {\n  let timeout: number | null = null\n\n  return {\n    debounce: (callback: () => void) => {\n      if (timeout) {\n        clearTimeout(timeout)\n      }\n      timeout = window.setTimeout(() => {\n        callback()\n        timeout = null\n      }, debounceTime)\n    },\n    clear: () => {\n      if (timeout) {\n        clearTimeout(timeout)\n        timeout = null\n      }\n    },\n  }\n}\n\n/**\n * Downloads data as a CSV file\n * @param rows - array of arrays representing the CSV rows\n * @param filename - the filename for the download (without extension)\n * @param headers - array of header strings\n */\nexport const downloadCSV = (rows: Array<Array<any>>, filename: string, headers: Array<string>) => {\n  if (rows.length === 0) {\n    return\n  }\n\n  const csvContent = [headers.join(\",\"), ...rows.map((row) => row.join(\",\"))].join(\"\\n\")\n\n  const blob = new Blob([csvContent], { type: \"text/csv;charset=utf-8;\" })\n  const link = document.createElement(\"a\")\n  const url = URL.createObjectURL(blob)\n  const today = new Date().toISOString().split(\"T\")[0]\n  const finalFilename = `${filename}_${today}.csv`\n\n  link.setAttribute(\"href\", url)\n  link.setAttribute(\"download\", finalFilename)\n  link.style.visibility = \"hidden\"\n\n  document.body.appendChild(link)\n  link.click()\n  document.body.removeChild(link)\n\n  // Clean up the URL object\n  URL.revokeObjectURL(url)\n}\n\n/**\n * Removes useless zeros from a string.\n * @param value - the string to remove zeros from\n * @returns string - the string without useless zeros\n * @example removeUselessZeros(\"1.000\") => \"1\"\n * @example removeUselessZeros(\"1.001\") => \"1.001\"\n * @example removeUselessZeros(\"1.0010\") => \"1,001\"\n */\nexport const removeUselessZeros = (value: string) => {\n  return value.replace(/(\\.\\d*?[1-9])0+$|\\.0+$/, \"$1\")\n}\n\n/**\n * Triggers a form submit event.\n * @param form - the form to submit\n */\nexport const triggerSubmit = (form: HTMLFormElement) => {\n  form.requestSubmit()\n}\n\n/**\n * Returns the rotation between 0 and 360.\n * @param rotation - the rotation to normalize\n * @returns number - the normalized rotation\n */\nexport const normalizeRotation = (rotation: number) => {\n  return (rotation % 360) + (rotation < 0 ? 360 : 0)\n}\n\nexport const OpenFoodFactsSlackLink = \"https://openfoodfacts.slack.com\"\nexport const FolksnomyEngineDocumentationLink = \"https://wiki.openfoodfacts.org/Folksonomy_Engine\"\nexport const FolksnomyEnginePropertyLink = \"https://wiki.openfoodfacts.org/Folksonomy/Property\"\n","import { openfoodfactsApiUrl } from \"../signals/openfoodfacts\"\nimport type {\n  BaseProductResponse,\n  NutrientsOrderRequest,\n  NutrientsParams,\n  RequestProductParams,\n} from \"../types/openfoodfacts\"\nimport { addParamsToUrl } from \"../utils\"\n\nenum ApiBaseUrl {\n  CGI = \"/cgi\",\n  API_V2 = \"/api/v2\",\n}\n\n/**\n * Get the url for the openfoodfacts api\n * @param path The path to the api\n * @param params The params to add to the url\n * @returns The url\n */\nconst getUrl = (path: string, params?: Record<string, any>) => {\n  const url = `${openfoodfactsApiUrl.get()}${path}`\n  if (!params) {\n    return url\n  }\n  return addParamsToUrl(url, params)\n}\n\n/**\n * Fetch product data from openfoodfacts\n * @param productCode The product code\n * @param params The params to add to the url\n * @returns The product data\n */\nexport async function fetchProduct<T>(productCode: string, params: RequestProductParams) {\n  const url = getUrl(`${ApiBaseUrl.API_V2}/product/${productCode}/`, params)\n  const response = await fetch(url)\n  if (!response.ok) {\n    throw new Error(\"Failed to fetch product data\")\n  }\n  return (await response.json()) as BaseProductResponse<T>\n}\n\n/**\n * Fetch nutrients order from openfoodfacts\n * @param params The params to add to the url\n * @returns The nutrients order\n */\nexport async function fetchNutrientsOrder(params: NutrientsParams) {\n  const url = getUrl(`${ApiBaseUrl.CGI}/nutrients.pl`, params)\n  const response = await fetch(url)\n  if (!response.ok) {\n    throw new Error(\"Failed to fetch nutrients order\")\n  }\n  return (await response.json()) as NutrientsOrderRequest\n}\n","import { signal } from \"@lit-labs/signals\"\nimport { SignalMap } from \"../utils/signals\"\nimport { fetchNutrientsOrder } from \"../api/openfoodfacts\"\nimport type { NutrientOrderRequest } from \"../types/openfoodfacts\"\n\nexport type NutrientsOrder = Record<string, { index: number; displayInEditForm: boolean }>\nexport const DEFAULT_OPENFOODFACTS_API_URL = \"https://world.openfoodfacts.org\"\n\n/**\n * Store the loading state of the taxonomies to avoid multiple requests.\n */\nconst nutrientsOrderPromises = new SignalMap<Promise<any>>({})\n\n// this enable changing open food facts URL globally\nexport const openfoodfactsApiUrl = signal(DEFAULT_OPENFOODFACTS_API_URL)\n\n/**\n * Nutrients order by country code\n */\nexport const nutrientsOrderByCountryCode = new SignalMap<NutrientsOrder>({})\n\n/**\n * Insert nutrient at index in NutrientsOrder if it's not already there\n *\n * @return {number} the next index\n */\nconst setOrderOfNutrient = (\n  obj: NutrientsOrder,\n  index: number,\n  nutrient: NutrientOrderRequest\n): number => {\n  if (obj.hasOwnProperty(nutrient.id)) {\n    return index\n  }\n  // set the order of the nutrient (the index\n  obj[nutrient.id] = {\n    index,\n    displayInEditForm: nutrient.display_in_edit_form,\n  }\n  index++\n  // if the nutrient has sub nutrients, set their order too recursively\n  if (nutrient.nutrients) {\n    for (const subNutrient of nutrient.nutrients) {\n      index = setOrderOfNutrient(obj, index, subNutrient)\n    }\n  }\n  return index\n}\n\n/**\n * Use Open Food Facts API to build an index of nutrients in the right order\n */\nexport const fetchNutrientsOrderByCountryCode = async (countryCode: string) => {\n  // check if the nutrients order is already in the cache\n  const nutrientsOrderPromise = nutrientsOrderPromises.getItem(countryCode)\n  if (nutrientsOrderPromise) {\n    // wait for the nutrients order to be loaded\n    await nutrientsOrderPromise\n    return\n  }\n  const request = fetchNutrientsOrder({ cc: countryCode })\n  let index = 0\n  nutrientsOrderPromises.setItem(countryCode, request)\n  const data = await request\n\n  const value: NutrientsOrder = {}\n  data.nutrients.forEach((nutrient) => {\n    index = setOrderOfNutrient(value, index, nutrient)\n  })\n  nutrientsOrderByCountryCode.setItem(countryCode, value)\n  return value\n}\n\nexport const sortKeysByNutrientsOrder = (countryCode: string, keys: string[]) => {\n  const nutrientsOrder = nutrientsOrderByCountryCode.getItem(countryCode)\n  if (!nutrientsOrder) {\n    return keys\n  }\n  // sort the keys based on the nutrients order, lower index first\n  return keys.sort((a, b) => {\n    const aIndex = nutrientsOrder[a]?.index ?? Infinity\n    const bIndex = nutrientsOrder[b]?.index ?? Infinity\n    return aIndex - bIndex\n  })\n}\n","import { robotoffConfiguration } from \"../../signals/robotoff\"\nimport { folksonomyConfiguration } from \"../../signals/folksonomy\"\nimport {\n  DEFAULT_ASSETS_IMAGES_PATH,\n  DEFAULT_LANGUAGE_CODE,\n  DEFAULT_ROBOTOFF_CONFIGURATION,\n  DEFAULT_FOLKSONOMY_CONFIGURATION,\n} from \"../../constants\"\nimport { LitElement } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type { OffWebcomponentConfigurationOptions } from \"../../types\"\nimport type { RobotoffConfigurationOptions } from \"../../types/robotoff\"\nimport type { FolksonomyConfigurationOptions } from \"../../types/folksonomy\"\nimport { setLanguageCode } from \"../../localization\"\nimport { assetsImagesPath, countryCode } from \"../../signals/app\"\nimport { DEFAULT_OPENFOODFACTS_API_URL, openfoodfactsApiUrl } from \"../../signals/openfoodfacts\"\n\n/**\n * The configuration properties of the webcomponent configuration element.\n * It is used to configure the app parameters.\n */\nconst CONFIGURATION_PROPERTIES: Record<\n  string,\n  {\n    propertyName: keyof OffWebcomponentConfigurationOptions\n    converter?: (value: string) => any\n    fn: (value: any) => void\n  }\n> = {\n  \"robotoff-configuration\": {\n    propertyName: \"robotoffConfiguration\",\n    converter: (value: string) => {\n      const configuration = JSON.parse(value)\n      return { ...DEFAULT_ROBOTOFF_CONFIGURATION, ...configuration }\n    },\n    fn: (value: RobotoffConfigurationOptions) => {\n      // Set the robotoff configuration\n      robotoffConfiguration.set(value)\n    },\n  },\n  \"language-code\": {\n    propertyName: \"languageCode\",\n    fn: (value: string) => {\n      // Set the language code\n      setLanguageCode(value)\n    },\n  },\n  \"country-code\": {\n    propertyName: \"countryCode\",\n    fn: (value: string) => {\n      // Set the country code\n      countryCode.set(value)\n    },\n  },\n  \"assets-images-path\": {\n    propertyName: \"assetsImagesPath\",\n    fn: (value: string) => {\n      assetsImagesPath.set(value)\n    },\n  },\n  \"folksonomy-configuration\": {\n    propertyName: \"folksonomyConfiguration\",\n    converter: (value: string) => {\n      const configuration = JSON.parse(value)\n      return { ...DEFAULT_FOLKSONOMY_CONFIGURATION, ...configuration }\n    },\n    fn: (value: FolksonomyConfigurationOptions) => {\n      // Set the folksonomy configuration\n      folksonomyConfiguration.set(value)\n    },\n  },\n  \"openfoodfacts-api-url\": {\n    propertyName: \"openfoodfactsApiUrl\",\n    fn: (value: string) => {\n      // Set the Open Food Facts API URL\n      openfoodfactsApiUrl.set(value)\n    },\n  },\n}\n\n/**\n * It is used to configure the OFF web components parmeters.\n * @element off-webcomponents-configuration\n */\n@customElement(\"off-webcomponents-configuration\")\nexport class OffWebcomponentsConfiguration extends LitElement {\n  /**\n   * The robotoff configuration object.\n   * @type {RobotoffConfigurationOptions}\n   */\n  @property({ type: Object, attribute: \"robotoff-configuration\", reflect: true })\n  robotoffConfiguration: RobotoffConfigurationOptions = {\n    ...DEFAULT_ROBOTOFF_CONFIGURATION,\n  }\n\n  /**\n   * The language code we need to use for the app.\n   * @attr language-code\n   */\n  @property({ type: String, attribute: \"language-code\", reflect: true })\n  languageCode?: string = DEFAULT_LANGUAGE_CODE\n\n  /**\n   * The country code we need to use for the app.\n   * @attr country-code\n   */\n  @property({ type: String, attribute: \"country-code\", reflect: true })\n  countryCode?: string\n\n  /**\n   * The image path we need to use to retrieve the images in assets/images folder.\n   * @attr image-path\n   */\n  @property({ type: String, attribute: \"assets-images-path\", reflect: true })\n  assetsImagesPath?: string = DEFAULT_ASSETS_IMAGES_PATH\n\n  /**\n   * The folksonomy configuration object.\n   * @type {FolksonomyConfigurationOptions}\n   */\n  @property({ type: Object, attribute: \"folksonomy-configuration\", reflect: true })\n  folksonomyConfiguration: FolksonomyConfigurationOptions = {\n    ...DEFAULT_FOLKSONOMY_CONFIGURATION,\n  }\n\n  /**\n   * The Open Food Facts API URL.\n   * @attr openfoodfacts-api-url\n   */\n  @property({ type: String, attribute: \"openfoodfacts-api-url\", reflect: true })\n  openfoodfactsApiUrl?: string = DEFAULT_OPENFOODFACTS_API_URL\n\n  override attributeChangedCallback(name: string, oldval: string, newval: string) {\n    super.attributeChangedCallback(name, oldval, newval)\n    if (name in CONFIGURATION_PROPERTIES) {\n      let value\n      const config = CONFIGURATION_PROPERTIES[name]\n      const propertyName = config.propertyName\n      if (CONFIGURATION_PROPERTIES[name].converter) {\n        value = CONFIGURATION_PROPERTIES[name].converter!(newval)\n      } else {\n        value = this[propertyName]\n      }\n      // Run the callback function that apply configuration\n      config.fn.call(this, value)\n    }\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"off-webcomponent-configuration\": OffWebcomponentsConfiguration\n  }\n}\n","export type RobotoffConfigurationOptions = {\n  apiUrl: string\n  dryRun: boolean\n  imgUrl: string\n}\n\nexport type QuestionRequestParams = Partial<{\n  insight_types: string\n  brand_filter: string\n  value_tag: string\n  country_filter: string\n  sort_by_popularity: boolean\n  campaign: string\n  predictor: string\n  lang: string\n}>\n\nexport type Question = {\n  barcode: string\n  server_type: string\n  type: string\n  value: string\n  question: string\n  insight_id: string\n  insight_type: string\n  value_tag: string\n  source_image_url: string\n}\n\nexport type QuestionsResponse = {\n  status: string\n  questions: Question[]\n}\n\n// https://openfoodfacts.github.io/robotoff/references/api/#tag/Insights/paths/~1insights~1annotate/post\nexport enum AnnotationAnswer {\n  ACCEPT_AND_ADD_DATA = 2,\n  ACCEPT = 1,\n  REFUSE = 0,\n  SKIP = -1,\n}\nexport enum InsightAnnotationSize {\n  CENTGRAMS = \"100g\",\n  SERVING = \"serving\",\n}\nexport enum QuestionAnnotationAnswer {\n  YES = \"1\",\n  NO = \"0\",\n  ANNOTATED = \"2\",\n  SKIP = \"-1\",\n} // https://openfoodfacts.github.io/robotoff/references/api/#tag/Insights/paths/~1insights~1annotate/post\n\nexport type InsightAnnotatationData = Record<string, { value: string; unit: string | null }>\n\nexport type InsightAnnotationAnswer = {\n  insightId: string\n  data: InsightAnnotatationData\n  type: InsightAnnotationSize\n}\n\nexport enum InsightType {\n  ingredient_spellcheck = \"ingredient_spellcheck\",\n  nutrient_extraction = \"nutrient_extraction\",\n  ingredient_detection = \"ingredient_detection\",\n}\n\nexport type InsightsRequestParams = Partial<{\n  lc: string[]\n  insight_types: string | string[]\n  barcode: string\n  annotated: boolean\n  annotation: number\n  value_tag: string\n  brands: string\n  countries: string\n  server_type: string\n  predictor: string\n  order_by: string\n  count: number\n  page: number\n  campaigns: string\n}>\n\nexport type NutrientInsightDatum = {\n  end: number\n  text: string\n  unit: string\n  score: number\n  start: number\n  valid: boolean\n  value: string\n  entity: string\n  char_end: number\n  char_start: number\n}\n\nexport type NutrientInsightData = {\n  entities: {\n    postprocessed: NutrientInsightDatum[]\n  }\n  nutrients: Record<string, NutrientInsightDatum>\n}\n\nexport type BaseInsight<DataType> = {\n  id: string\n  barcode: string\n  type: string\n  timestamp: string | null\n  completed_at: string | null\n  annotation: string | null\n  annotated_result: string | null\n  n_votes: number\n  username: string | null\n  countries: string[]\n  brands: string[]\n  process_after: string | null\n  value_tag: string | null\n  value: string | null\n  source_image: string | null\n  automatic_processing: boolean\n  server_type: string\n  unique_scans_n: number\n  reserved_barcode: boolean\n  predictor: string\n  predictor_version: string\n  campaign: string[]\n  confidence: number | null\n  bounding_box: string | null\n  data: DataType\n}\n\nexport type NutrientsInsight = BaseInsight<NutrientInsightData>\n\nexport type IngredientSpellcheckInsight = BaseInsight<{\n  lang: string\n  original: string\n  correction: string\n  lang_confidence: number\n}>\n\ninterface Lang {\n  lang: string\n  confidence: number\n}\n\ninterface IngredientDetection {\n  id: string\n  text: string\n  vegan?: string\n  vegetarian?: string\n  in_taxonomy: boolean\n  ingredients?: IngredientDetection[]\n  is_in_taxonomy?: number\n  ciqual_food_code?: string\n  ciqual_proxy_food_code?: string\n  from_palm_oil?: string\n  percent_estimate: number\n  percent_max?: number\n  percent_min?: number\n  ecobalyse_code?: string\n  processing?: string\n  labels?: string\n  bounding_box?: RobotoffBoundingBox\n}\n\nexport type IngredientDetectionInsight = BaseInsight<{\n  end: number\n  lang: Lang\n  text: string\n  score: number\n  start: number\n  raw_end: number\n  priority: number\n  ingredients: IngredientDetection[]\n  bounding_box: RobotoffBoundingBox\n  ingredients_n: number\n  known_ingredients_n: number\n  unknown_ingredients_n: number\n  fraction_known_ingredients: number\n  rotation: number\n}>\n\nexport type InsightsResponse<\n  T extends NutrientsInsight | IngredientSpellcheckInsight | IngredientDetectionInsight,\n> = {\n  count: number\n  status: string\n  insights: T[]\n}\n\nexport type NutrientAnotationFormData = {\n  value: string\n  unit: string | null\n}\n\nexport type NutrientsAnnotationData = {\n  serving_size: string | null\n  nutrients: Record<string, NutrientAnotationFormData>\n  nutrition_data_per: string\n}\n\nexport type AnnotationFormData = {\n  insight_id: string\n  annotation: AnnotationAnswer\n  data?: string\n}\n\nexport type ImagePredictionsRequestParams = {\n  count: number\n  page: number\n  barcode: string\n  model_name: string\n  min_confidence: number\n}\n\nexport type IngredientPrediction = {\n  id: string\n  text: string\n  vegan?: string\n  vegetarian?: string\n  in_taxonomy: boolean\n  percent_max: number\n  percent_min: number\n  is_in_taxonomy: number\n  percent_estimate: number\n  ciqual_proxy_food_code?: string\n  ingredients?: IngredientPrediction[]\n}\nexport type RobotoffBoundingBox = [number, number, number, number]\n\nexport type IngredientDetectionAnnotationData = {\n  annotation: string\n  bounding_box: RobotoffBoundingBox\n  rotation: number\n}\n","const PATH_PARAM_RE = /\\{[^{}]+\\}/g;\nconst supportsRequestInitExt = () => {\n  return typeof process === \"object\" && Number.parseInt(process?.versions?.node?.substring(0, 2)) >= 18 && process.versions.undici;\n};\nfunction randomID() {\n  return Math.random().toString(36).slice(2, 11);\n}\nfunction createClient(clientOptions) {\n  let {\n    baseUrl = \"\",\n    Request: CustomRequest = globalThis.Request,\n    fetch: baseFetch = globalThis.fetch,\n    querySerializer: globalQuerySerializer,\n    bodySerializer: globalBodySerializer,\n    headers: baseHeaders,\n    requestInitExt = void 0,\n    ...baseOptions\n  } = { ...clientOptions };\n  requestInitExt = supportsRequestInitExt() ? requestInitExt : void 0;\n  baseUrl = removeTrailingSlash(baseUrl);\n  const middlewares = [];\n  async function coreFetch(schemaPath, fetchOptions) {\n    const {\n      baseUrl: localBaseUrl,\n      fetch = baseFetch,\n      Request = CustomRequest,\n      headers,\n      params = {},\n      parseAs = \"json\",\n      querySerializer: requestQuerySerializer,\n      bodySerializer = globalBodySerializer ?? defaultBodySerializer,\n      body,\n      ...init\n    } = fetchOptions || {};\n    let finalBaseUrl = baseUrl;\n    if (localBaseUrl) {\n      finalBaseUrl = removeTrailingSlash(localBaseUrl) ?? baseUrl;\n    }\n    let querySerializer = typeof globalQuerySerializer === \"function\" ? globalQuerySerializer : createQuerySerializer(globalQuerySerializer);\n    if (requestQuerySerializer) {\n      querySerializer = typeof requestQuerySerializer === \"function\" ? requestQuerySerializer : createQuerySerializer({\n        ...typeof globalQuerySerializer === \"object\" ? globalQuerySerializer : {},\n        ...requestQuerySerializer\n      });\n    }\n    const serializedBody = body === void 0 ? void 0 : bodySerializer(\n      body,\n      // Note: we declare mergeHeaders() both here and below because it’s a bit of a chicken-or-egg situation:\n      // bodySerializer() needs all headers so we aren’t dropping ones set by the user, however,\n      // the result of this ALSO sets the lowest-priority content-type header. So we re-merge below,\n      // setting the content-type at the very beginning to be overwritten.\n      // Lastly, based on the way headers work, it’s not a simple “present-or-not” check becauase null intentionally un-sets headers.\n      mergeHeaders(baseHeaders, headers, params.header)\n    );\n    const finalHeaders = mergeHeaders(\n      // with no body, we should not to set Content-Type\n      serializedBody === void 0 || // if serialized body is FormData; browser will correctly set Content-Type & boundary expression\n      serializedBody instanceof FormData ? {} : {\n        \"Content-Type\": \"application/json\"\n      },\n      baseHeaders,\n      headers,\n      params.header\n    );\n    const requestInit = {\n      redirect: \"follow\",\n      ...baseOptions,\n      ...init,\n      body: serializedBody,\n      headers: finalHeaders\n    };\n    let id;\n    let options;\n    let request = new CustomRequest(\n      createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer }),\n      requestInit\n    );\n    let response;\n    for (const key in init) {\n      if (!(key in request)) {\n        request[key] = init[key];\n      }\n    }\n    if (middlewares.length) {\n      id = randomID();\n      options = Object.freeze({\n        baseUrl: finalBaseUrl,\n        fetch,\n        parseAs,\n        querySerializer,\n        bodySerializer\n      });\n      for (const m of middlewares) {\n        if (m && typeof m === \"object\" && typeof m.onRequest === \"function\") {\n          const result = await m.onRequest({\n            request,\n            schemaPath,\n            params,\n            options,\n            id\n          });\n          if (result) {\n            if (result instanceof CustomRequest) {\n              request = result;\n            } else if (result instanceof Response) {\n              response = result;\n              break;\n            } else {\n              throw new Error(\"onRequest: must return new Request() or Response() when modifying the request\");\n            }\n          }\n        }\n      }\n    }\n    if (!response) {\n      try {\n        response = await fetch(request, requestInitExt);\n      } catch (error2) {\n        let errorAfterMiddleware = error2;\n        if (middlewares.length) {\n          for (let i = middlewares.length - 1; i >= 0; i--) {\n            const m = middlewares[i];\n            if (m && typeof m === \"object\" && typeof m.onError === \"function\") {\n              const result = await m.onError({\n                request,\n                error: errorAfterMiddleware,\n                schemaPath,\n                params,\n                options,\n                id\n              });\n              if (result) {\n                if (result instanceof Response) {\n                  errorAfterMiddleware = void 0;\n                  response = result;\n                  break;\n                }\n                if (result instanceof Error) {\n                  errorAfterMiddleware = result;\n                  continue;\n                }\n                throw new Error(\"onError: must return new Response() or instance of Error\");\n              }\n            }\n          }\n        }\n        if (errorAfterMiddleware) {\n          throw errorAfterMiddleware;\n        }\n      }\n      if (middlewares.length) {\n        for (let i = middlewares.length - 1; i >= 0; i--) {\n          const m = middlewares[i];\n          if (m && typeof m === \"object\" && typeof m.onResponse === \"function\") {\n            const result = await m.onResponse({\n              request,\n              response,\n              schemaPath,\n              params,\n              options,\n              id\n            });\n            if (result) {\n              if (!(result instanceof Response)) {\n                throw new Error(\"onResponse: must return new Response() when modifying the response\");\n              }\n              response = result;\n            }\n          }\n        }\n      }\n    }\n    if (response.status === 204 || request.method === \"HEAD\" || response.headers.get(\"Content-Length\") === \"0\") {\n      return response.ok ? { data: void 0, response } : { error: void 0, response };\n    }\n    if (response.ok) {\n      if (parseAs === \"stream\") {\n        return { data: response.body, response };\n      }\n      return { data: await response[parseAs](), response };\n    }\n    let error = await response.text();\n    try {\n      error = JSON.parse(error);\n    } catch {\n    }\n    return { error, response };\n  }\n  return {\n    request(method, url, init) {\n      return coreFetch(url, { ...init, method: method.toUpperCase() });\n    },\n    /** Call a GET endpoint */\n    GET(url, init) {\n      return coreFetch(url, { ...init, method: \"GET\" });\n    },\n    /** Call a PUT endpoint */\n    PUT(url, init) {\n      return coreFetch(url, { ...init, method: \"PUT\" });\n    },\n    /** Call a POST endpoint */\n    POST(url, init) {\n      return coreFetch(url, { ...init, method: \"POST\" });\n    },\n    /** Call a DELETE endpoint */\n    DELETE(url, init) {\n      return coreFetch(url, { ...init, method: \"DELETE\" });\n    },\n    /** Call a OPTIONS endpoint */\n    OPTIONS(url, init) {\n      return coreFetch(url, { ...init, method: \"OPTIONS\" });\n    },\n    /** Call a HEAD endpoint */\n    HEAD(url, init) {\n      return coreFetch(url, { ...init, method: \"HEAD\" });\n    },\n    /** Call a PATCH endpoint */\n    PATCH(url, init) {\n      return coreFetch(url, { ...init, method: \"PATCH\" });\n    },\n    /** Call a TRACE endpoint */\n    TRACE(url, init) {\n      return coreFetch(url, { ...init, method: \"TRACE\" });\n    },\n    /** Register middleware */\n    use(...middleware) {\n      for (const m of middleware) {\n        if (!m) {\n          continue;\n        }\n        if (typeof m !== \"object\" || !(\"onRequest\" in m || \"onResponse\" in m || \"onError\" in m)) {\n          throw new Error(\"Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`\");\n        }\n        middlewares.push(m);\n      }\n    },\n    /** Unregister middleware */\n    eject(...middleware) {\n      for (const m of middleware) {\n        const i = middlewares.indexOf(m);\n        if (i !== -1) {\n          middlewares.splice(i, 1);\n        }\n      }\n    }\n  };\n}\nclass PathCallForwarder {\n  constructor(client, url) {\n    this.client = client;\n    this.url = url;\n  }\n  GET = (init) => {\n    return this.client.GET(this.url, init);\n  };\n  PUT = (init) => {\n    return this.client.PUT(this.url, init);\n  };\n  POST = (init) => {\n    return this.client.POST(this.url, init);\n  };\n  DELETE = (init) => {\n    return this.client.DELETE(this.url, init);\n  };\n  OPTIONS = (init) => {\n    return this.client.OPTIONS(this.url, init);\n  };\n  HEAD = (init) => {\n    return this.client.HEAD(this.url, init);\n  };\n  PATCH = (init) => {\n    return this.client.PATCH(this.url, init);\n  };\n  TRACE = (init) => {\n    return this.client.TRACE(this.url, init);\n  };\n}\nclass PathClientProxyHandler {\n  constructor() {\n    this.client = null;\n  }\n  // Assume the property is an URL.\n  get(coreClient, url) {\n    const forwarder = new PathCallForwarder(coreClient, url);\n    this.client[url] = forwarder;\n    return forwarder;\n  }\n}\nfunction wrapAsPathBasedClient(coreClient) {\n  const handler = new PathClientProxyHandler();\n  const proxy = new Proxy(coreClient, handler);\n  function Client() {\n  }\n  Client.prototype = proxy;\n  const client = new Client();\n  handler.client = client;\n  return client;\n}\nfunction createPathBasedClient(clientOptions) {\n  return wrapAsPathBasedClient(createClient(clientOptions));\n}\nfunction serializePrimitiveParam(name, value, options) {\n  if (value === void 0 || value === null) {\n    return \"\";\n  }\n  if (typeof value === \"object\") {\n    throw new Error(\n      \"Deeply-nested arrays/objects aren\\u2019t supported. Provide your own `querySerializer()` to handle these.\"\n    );\n  }\n  return `${name}=${options?.allowReserved === true ? value : encodeURIComponent(value)}`;\n}\nfunction serializeObjectParam(name, value, options) {\n  if (!value || typeof value !== \"object\") {\n    return \"\";\n  }\n  const values = [];\n  const joiner = {\n    simple: \",\",\n    label: \".\",\n    matrix: \";\"\n  }[options.style] || \"&\";\n  if (options.style !== \"deepObject\" && options.explode === false) {\n    for (const k in value) {\n      values.push(k, options.allowReserved === true ? value[k] : encodeURIComponent(value[k]));\n    }\n    const final2 = values.join(\",\");\n    switch (options.style) {\n      case \"form\": {\n        return `${name}=${final2}`;\n      }\n      case \"label\": {\n        return `.${final2}`;\n      }\n      case \"matrix\": {\n        return `;${name}=${final2}`;\n      }\n      default: {\n        return final2;\n      }\n    }\n  }\n  for (const k in value) {\n    const finalName = options.style === \"deepObject\" ? `${name}[${k}]` : k;\n    values.push(serializePrimitiveParam(finalName, value[k], options));\n  }\n  const final = values.join(joiner);\n  return options.style === \"label\" || options.style === \"matrix\" ? `${joiner}${final}` : final;\n}\nfunction serializeArrayParam(name, value, options) {\n  if (!Array.isArray(value)) {\n    return \"\";\n  }\n  if (options.explode === false) {\n    const joiner2 = { form: \",\", spaceDelimited: \"%20\", pipeDelimited: \"|\" }[options.style] || \",\";\n    const final = (options.allowReserved === true ? value : value.map((v) => encodeURIComponent(v))).join(joiner2);\n    switch (options.style) {\n      case \"simple\": {\n        return final;\n      }\n      case \"label\": {\n        return `.${final}`;\n      }\n      case \"matrix\": {\n        return `;${name}=${final}`;\n      }\n      // case \"spaceDelimited\":\n      // case \"pipeDelimited\":\n      default: {\n        return `${name}=${final}`;\n      }\n    }\n  }\n  const joiner = { simple: \",\", label: \".\", matrix: \";\" }[options.style] || \"&\";\n  const values = [];\n  for (const v of value) {\n    if (options.style === \"simple\" || options.style === \"label\") {\n      values.push(options.allowReserved === true ? v : encodeURIComponent(v));\n    } else {\n      values.push(serializePrimitiveParam(name, v, options));\n    }\n  }\n  return options.style === \"label\" || options.style === \"matrix\" ? `${joiner}${values.join(joiner)}` : values.join(joiner);\n}\nfunction createQuerySerializer(options) {\n  return function querySerializer(queryParams) {\n    const search = [];\n    if (queryParams && typeof queryParams === \"object\") {\n      for (const name in queryParams) {\n        const value = queryParams[name];\n        if (value === void 0 || value === null) {\n          continue;\n        }\n        if (Array.isArray(value)) {\n          if (value.length === 0) {\n            continue;\n          }\n          search.push(\n            serializeArrayParam(name, value, {\n              style: \"form\",\n              explode: true,\n              ...options?.array,\n              allowReserved: options?.allowReserved || false\n            })\n          );\n          continue;\n        }\n        if (typeof value === \"object\") {\n          search.push(\n            serializeObjectParam(name, value, {\n              style: \"deepObject\",\n              explode: true,\n              ...options?.object,\n              allowReserved: options?.allowReserved || false\n            })\n          );\n          continue;\n        }\n        search.push(serializePrimitiveParam(name, value, options));\n      }\n    }\n    return search.join(\"&\");\n  };\n}\nfunction defaultPathSerializer(pathname, pathParams) {\n  let nextURL = pathname;\n  for (const match of pathname.match(PATH_PARAM_RE) ?? []) {\n    let name = match.substring(1, match.length - 1);\n    let explode = false;\n    let style = \"simple\";\n    if (name.endsWith(\"*\")) {\n      explode = true;\n      name = name.substring(0, name.length - 1);\n    }\n    if (name.startsWith(\".\")) {\n      style = \"label\";\n      name = name.substring(1);\n    } else if (name.startsWith(\";\")) {\n      style = \"matrix\";\n      name = name.substring(1);\n    }\n    if (!pathParams || pathParams[name] === void 0 || pathParams[name] === null) {\n      continue;\n    }\n    const value = pathParams[name];\n    if (Array.isArray(value)) {\n      nextURL = nextURL.replace(match, serializeArrayParam(name, value, { style, explode }));\n      continue;\n    }\n    if (typeof value === \"object\") {\n      nextURL = nextURL.replace(match, serializeObjectParam(name, value, { style, explode }));\n      continue;\n    }\n    if (style === \"matrix\") {\n      nextURL = nextURL.replace(match, `;${serializePrimitiveParam(name, value)}`);\n      continue;\n    }\n    nextURL = nextURL.replace(match, style === \"label\" ? `.${encodeURIComponent(value)}` : encodeURIComponent(value));\n  }\n  return nextURL;\n}\nfunction defaultBodySerializer(body, headers) {\n  if (body instanceof FormData) {\n    return body;\n  }\n  if (headers) {\n    const contentType = headers.get instanceof Function ? headers.get(\"Content-Type\") ?? headers.get(\"content-type\") : headers[\"Content-Type\"] ?? headers[\"content-type\"];\n    if (contentType === \"application/x-www-form-urlencoded\") {\n      return new URLSearchParams(body).toString();\n    }\n  }\n  return JSON.stringify(body);\n}\nfunction createFinalURL(pathname, options) {\n  let finalURL = `${options.baseUrl}${pathname}`;\n  if (options.params?.path) {\n    finalURL = defaultPathSerializer(finalURL, options.params.path);\n  }\n  let search = options.querySerializer(options.params.query ?? {});\n  if (search.startsWith(\"?\")) {\n    search = search.substring(1);\n  }\n  if (search) {\n    finalURL += `?${search}`;\n  }\n  return finalURL;\n}\nfunction mergeHeaders(...allHeaders) {\n  const finalHeaders = new Headers();\n  for (const h of allHeaders) {\n    if (!h || typeof h !== \"object\") {\n      continue;\n    }\n    const iterator = h instanceof Headers ? h.entries() : Object.entries(h);\n    for (const [k, v] of iterator) {\n      if (v === null) {\n        finalHeaders.delete(k);\n      } else if (Array.isArray(v)) {\n        for (const v2 of v) {\n          finalHeaders.append(k, v2);\n        }\n      } else if (v !== void 0) {\n        finalHeaders.set(k, v);\n      }\n    }\n  }\n  return finalHeaders;\n}\nfunction removeTrailingSlash(url) {\n  if (url.endsWith(\"/\")) {\n    return url.substring(0, url.length - 1);\n  }\n  return url;\n}\n\nexport { createFinalURL, createPathBasedClient, createQuerySerializer, createClient as default, defaultBodySerializer, defaultPathSerializer, mergeHeaders, randomID, removeTrailingSlash, serializeArrayParam, serializeObjectParam, serializePrimitiveParam, wrapAsPathBasedClient };\n//# sourceMappingURL=index.mjs.map\n","// auto-generated\nexport const VERSION = \"2.0.0-alpha.19\";\n//# sourceMappingURL=version.js.map","export const STATIC_HOST = \"https://static.openfoodfacts.org\";\nimport { VERSION } from \"./version.js\";\nexport const USER_AGENT = `OpenFoodFacts - NodeJS ${VERSION}`;\n/* eslint-disable no-unused-vars */\nexport var BackendType;\n(function (BackendType) {\n    BackendType[\"OFF\"] = \"OFF\";\n    BackendType[\"OBF\"] = \"OBF\";\n    BackendType[\"OPFF\"] = \"OPFF\";\n    BackendType[\"OPF\"] = \"OPF\";\n})(BackendType || (BackendType = {}));\nexport const BACKEND_DOMAINS = {\n    [BackendType.OFF]: \"openfoodfacts.org\",\n    [BackendType.OBF]: \"openbeautyfacts.org\",\n    [BackendType.OPFF]: \"openpetfoodfacts.org\",\n    [BackendType.OPF]: \"openproductsfacts.org\",\n};\nexport const BACKEND_NAMES = {\n    [BackendType.OFF]: \"OpenFoodFacts\",\n    [BackendType.OBF]: \"OpenBeautyFacts\",\n    [BackendType.OPFF]: \"OpenPetFoodFacts\",\n    [BackendType.OPF]: \"OpenProductsFacts\",\n};\nexport const DEFAULT_FOLKSONOMY_API_URL = \"https://api.folksonomy.openfoodfacts.org\";\nexport const DEFAULT_ROBOTOFF_API_URL = \"https://robotoff.openfoodfacts.org/api/v1\";\nexport const DEFAULT_NUTRIPATROL_API_URL = \"https://nutripatrol.openfoodfacts.org\";\nexport const PRODUCT_IMAGE_BASE_URL = \"https://images.openfoodfacts.org/images/products\";\nexport const PRODUCT_API_HOST = \"https://world.openfoodfacts.org\";\nexport const PRODUCT_IMAGE_URL = (path) => `${PRODUCT_IMAGE_BASE_URL}/${path}`;\n//# sourceMappingURL=consts.js.map","export function formBody(params) {\n    const formBody = new URLSearchParams();\n    for (const [key, value] of Object.entries(params)) {\n        if (value === null || value === undefined) {\n            // typeof null === object\n            // typeof undefined === undefined\n            continue;\n        }\n        switch (typeof value) {\n            case \"string\":\n                formBody.append(key, value);\n                break;\n            case \"boolean\":\n            case \"number\":\n            case \"bigint\":\n                formBody.append(key, String(value));\n                break;\n            case \"object\":\n                formBody.append(key, JSON.stringify(value));\n                break;\n            default:\n                throw new Error(`Cannot formBody-fy a ${typeof value}!`);\n        }\n    }\n    return formBody.toString();\n}\n//# sourceMappingURL=formbody.js.map","import createClient from \"openapi-fetch\";\nimport { DEFAULT_ROBOTOFF_API_URL, USER_AGENT } from \"./consts.js\";\nimport { formBody } from \"./formbody.js\";\nexport class Robotoff {\n    constructor(fetch, options = { baseUrl: DEFAULT_ROBOTOFF_API_URL }) {\n        this.fetch = fetch;\n        this.raw = createClient({\n            fetch: this.fetch,\n            baseUrl: options.baseUrl,\n            headers: {\n                \"User-Agent\": USER_AGENT,\n            },\n        });\n    }\n    async annotate(body) {\n        return this.raw.POST(\"/insights/annotate\", {\n            body: body,\n            headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n            bodySerializer: formBody,\n        });\n    }\n    questionsByProductCode(code, query) {\n        return this.raw.GET(\"/questions/{barcode}\", {\n            params: { path: { barcode: code }, query: query },\n        });\n    }\n    insightDetail(id) {\n        return this.raw.GET(\"/insights/detail/{insight_id}\", {\n            params: { path: { insight_id: id } },\n        });\n    }\n    /**\n     * Fetches insights based on the provided query.\n     *\n     * @param {RobotoffInsightQuery} query - The query object containing parameters for fetching insights.\n     * @returns A promise that resolves to the data from the insights endpoint\n     *\n     */\n    insights(query) {\n        return this.raw.GET(\"/insights\", { params: { query } });\n    }\n    // TODO: replace any with proper type\n    // ATM not specifying the type makes tsc fail sometimes\n    async loadLogo(logoId) {\n        // @ts-expect-error TODO: still not documented\n        const result = await this.raw.GET(\"/images/logos/{logoId}\", {\n            params: { path: { logoId } },\n        });\n        return result.data;\n    }\n}\n//# sourceMappingURL=robotoff.js.map","import { STATIC_HOST } from \"../consts.js\";\nexport const TAXONOMY_URL = (taxo) => `${STATIC_HOST}/data/taxonomies/${taxo}.json`;\n//# sourceMappingURL=api.js.map","export function formData(data) {\n    const form = new FormData();\n    const entries = Object.entries(data !== null && data !== void 0 ? data : {});\n    for (const [key, value] of entries) {\n        if (value == null)\n            continue;\n        form.append(key, value);\n    }\n    return form;\n}\n//# sourceMappingURL=openapi.js.map","import createClient from \"openapi-fetch\";\nimport { formData } from \"./openapi.js\";\nimport { USER_AGENT } from \"./consts.js\";\n/**\n * The OpenFoodFacts main API client for version 2.\n *\n * You should not use this class directly, instead use the `OpenFoodFactsApi` class.\n */\nexport class ProductOpenerApiV2 {\n    constructor(fetch, options) {\n        this.fetch = fetch;\n        this.baseUrl = options.host;\n        this.client = createClient({\n            fetch: this.fetch,\n            baseUrl: this.baseUrl,\n        });\n    }\n    /**\n     * Get a taxonomy entry by its type and ID.\n     * @param taxo - The type of taxonomy (e.g., \"categories\", \"brands\").\n     * @param entry - The ID of the taxonomy entry.\n     */\n    async getTaxoEntry(taxo, entry) {\n        const res = await this.fetch(`${this.baseUrl}/api/v2/taxonomy?tagtype=${taxo}&tags=${entry}`);\n        return (await res.json());\n    }\n    /**\n     * Performs OCR on a product image.\n     * @example const {data, error} = await performOCR(barcode, photoId, ocrEngine);\n     */\n    async performOCR(barcode, photoId, ocrEngine = \"google_cloud_vision\") {\n        return this.client.GET(\"/cgi/ingredients.pl\", {\n            params: {\n                query: {\n                    code: barcode,\n                    id: photoId,\n                    ocr_engine: ocrEngine,\n                    process_image: \"1\",\n                },\n            },\n        });\n    }\n    /**\n     * @example const {data, error} = await search(query);\n     */\n    async search(query) {\n        return this.client.GET(\"/api/v2/search\", {\n            params: { query },\n        });\n    }\n    /**\n     * Returns all available attribute groups\n     * @returns A promise that resolves to an array of attribute groups\n     * @example\n     * const {data, error} = await getAttributeGroups();\n     */\n    async getAttributeGroups() {\n        return this.client.GET(\"/api/v2/attribute_groups\");\n    }\n    /**\n     * Unselects an image for a product\n     * @param barcode - The barcode of the product\n     * @param id - Image field (image id) of the photo to unselect (e.g., \"front_fr\")\n     * @returns A promise that resolves to the unselect response\n     */\n    async unselectImage(barcode, id) {\n        return this.client.POST(\"/cgi/product_image_unselect.pl\", {\n            body: { code: barcode, id: id },\n        });\n    }\n    /**\n     * Returns product attributes for a given barcode\n     * @param barcode - The barcode of the product\n     * @returns A promise that resolves to an array of product attributes\n     */\n    async getProductAttributes(barcode) {\n        var _a, _b;\n        const res = await this.client.GET(\"/api/v2/product/{barcode}\", {\n            params: {\n                path: { barcode },\n                query: { fields: \"product_name,code,attribute_groups_en\" },\n            },\n        });\n        // @ts-expect-error - OpenAPI schema may not include all possible fields\n        return ((_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.product) === null || _b === void 0 ? void 0 : _b.attribute_groups_en) || [];\n    }\n    /**\n     * Adds or edits a product using the V2 API\n     * @param product - The product data to add or edit\n     * @param credentials - Optional credentials for authentication\n     * @returns A promise that resolves to true if successful, false otherwise\n     */\n    async addOrEditProductV2(product, credentials) {\n        var _a;\n        const url = `${this.baseUrl}/cgi/product_jqm2.pl`;\n        const languageCodes = Object.keys(product.languages_codes || {});\n        const productNames = languageCodes.reduce((acc, lang) => {\n            const productName = getProductNameInLang(product, lang);\n            if (productName != null) {\n                acc[`product_name_${lang}`] = productName;\n            }\n            return acc;\n        }, {});\n        const ingredientsTexts = languageCodes.reduce((acc, lang) => {\n            const ingredientsText = getProductIngredientsInLang(product, lang);\n            if (ingredientsText != null) {\n                acc[`ingredients_text_${lang}`] = ingredientsText;\n            }\n            return acc;\n        }, {});\n        const body = formData(Object.assign(Object.assign({ code: product.code, user_id: credentials === null || credentials === void 0 ? void 0 : credentials.username, password: credentials === null || credentials === void 0 ? void 0 : credentials.password, categories: product.categories || \"\", labels: product.labels || \"\", brands: product.brands || \"\", quantity: product.quantity || \"\", serving_size: product.serving_size || \"\", stores: product.stores || \"\", origins: product.origins || \"\", countries: product.countries || \"\", emb_codes: product.emb_codes || \"\", packaging: product.packaging || \"\", manufacturing_places: product.manufacturing_places || \"\", comment: (_a = product.comment) !== null && _a !== void 0 ? _a : \"\", product_name: product.product_name || \"\", ingredients_text: product.ingredients_text || \"\" }, productNames), ingredientsTexts));\n        const res = await this.fetch(url, {\n            method: \"POST\",\n            body,\n            headers: {\n                \"User-Agent\": USER_AGENT,\n            },\n        });\n        return res.status === 200;\n    }\n    /**\n     * Crops and selects an image for a product\n     * @param barcode - The barcode of the product\n     * @param imgid - Identifier of the image to select (should be a number)\n     * @param id - Identifier of the selected image field (format: {IMAGE_TYPE}_{LANG})\n     * @param cropData - Crop coordinates and options\n     * @returns A promise that resolves to the crop response\n     *\n     * @example\n     * const {data, error} = await cropImage(barcode, imgid, id, cropData);\n     */\n    async cropImage(barcode, imgid, id, cropData) {\n        return this.client.POST(\"/cgi/product_image_crop.pl\", {\n            body: {\n                code: barcode,\n                imgid: imgid,\n                id: id,\n                x1: cropData.x1,\n                y1: cropData.y1,\n                x2: cropData.x2,\n                y2: cropData.y2,\n                angle: cropData.angle,\n                normalize: cropData.normalize ? \"true\" : \"false\",\n                white_magic: cropData.white_magic ? \"true\" : \"false\",\n                comment: cropData.comment,\n                app_name: cropData.app_name,\n                app_version: cropData.app_version,\n                app_uuid: cropData.app_uuid,\n                \"User-Agent\": cropData.user_agent,\n            },\n        });\n    }\n    /**\n     * Uploads an image to OpenFoodFacts for a product.\n     * @param barcode - The barcode of the product\n     * @param imageFile - The image file to upload\n     * @param imagefield - The field name for the image (e.g., \"front\", \"ingredients\", \"nutrition\")\n     * @returns A promise that resolves to the upload response\n     */\n    async uploadImage(barcode, imageFile, imagefield) {\n        return this.client.POST(\"/cgi/product_image_upload.pl\", {\n            // @ts-expect-error - OpenAPI schema wrong\n            body: {\n                code: barcode,\n                imagefield: imagefield,\n                [`imgupload_${imagefield}`]: imageFile,\n                \"User-Agent\": USER_AGENT,\n            },\n            bodySerializer: formData,\n        });\n    }\n    /**\n     * Rotates an image for a product\n     * @param barcode - The barcode of the product\n     * @param id - Identifier of the selected image field (format: {IMAGE_TYPE}_{LANG})\n     * @param imgid - Identifier of the image to rotate (should be a number as string)\n     * @param angle - Angle of rotation in degrees (90, 180, or 270 clockwise)\n     * @returns A promise that resolves to the rotation response\n     */\n    async rotateImage(barcode, id, imgid, angle) {\n        return await this.client.GET(\"/cgi/product_image_crop.pl\", {\n            params: {\n                query: {\n                    code: barcode,\n                    id: id,\n                    imgid: imgid,\n                    angle: angle,\n                },\n            },\n        });\n    }\n    /**\n     * Returns product data using the V2 API\n     * @param barcode - The barcode of the product\n     * @returns A promise that resolves to the product data or undefined if not found\n     * @example\n     * const {data, error} = await getProductV2(barcode);\n     */\n    async getProductV2(barcode) {\n        return this.client.GET(\"/api/v2/product/{barcode}\", {\n            params: { path: { barcode } },\n        });\n    }\n    /**\n     * Returns an array of image names for the product\n     * @param barcode - The barcode of the product\n     * @returns A promise that resolves to an array of image names or null if not found\n     */\n    async getProductImages(barcode) {\n        var _a, _b;\n        const res = await this.client.GET(\"/api/v2/product/{barcode}\", {\n            params: {\n                query: { fields: \"images\" },\n                path: { barcode },\n            },\n        });\n        const product = (_a = res.data) === null || _a === void 0 ? void 0 : _a.product;\n        // Check if the returned type has images\n        if (!product)\n            return null;\n        if (!(\"images\" in product))\n            return null;\n        const images = (_b = product.images) !== null && _b !== void 0 ? _b : {};\n        return Object.keys(images);\n    }\n}\nexport function getProductNameInLang(product, lang) {\n    var _a;\n    return (_a = product[`product_name_${lang}`]) !== null && _a !== void 0 ? _a : product.product_name;\n}\nexport function getProductIngredientsInLang(product, lang) {\n    var _a;\n    return (_a = product[`ingredients_text_${lang}`]) !== null && _a !== void 0 ? _a : product.ingredients_text;\n}\n//# sourceMappingURL=off-v2.js.map","import createClient from \"openapi-fetch\";\nexport class ProductOpenerApiV3 {\n    constructor(fetch, options) {\n        this.fetch = fetch;\n        this.baseUrl = options.host;\n        this.client = createClient({\n            fetch: this.fetch,\n            baseUrl: this.baseUrl,\n        });\n    }\n    async uploadProductImage(barcode, params) {\n        return this.client.POST(\"/api/v3/product/{barcode}/images\", {\n            params: { path: { barcode } },\n            body: Object.assign({}, params),\n        });\n    }\n    /**\n     * Deletes an uploaded image for a product\n     * @param barcode - The barcode of the product corresponding to the image\n     * @param imgid - The id of the image to be deleted\n     * @returns A promise that resolves to the deletion response\n     */\n    async deleteProductImage(barcode, imgid) {\n        return await this.client.DELETE(\"/api/v3/product/{barcode}/images/uploaded/{imgid}\", { params: { path: { barcode, imgid } } });\n    }\n    /**\n     * Returns product details by barcode with optional fields\n     * @param barcode - The barcode of the product\n     * @param query - An optional query object to filter the returned fields\n     * @template T - An array of keys from ProductV3 to return\n     * @example\n     * ```typescript\n     * const result = await api.getProductV3(\"1234567890123\", { fields: [\"product_name\", \"brands\"] });\n     * console.log(result.product.product_name, result.product.brands);\n     * ```\n     * @returns A promise that resolves to a product object with the specified fields or undefined if not found\n     */\n    async getProductV3(barcode, query) {\n        var _a;\n        const { error, data } = await this.client.GET(\"/api/v3/product/{barcode}\", {\n            params: {\n                path: { barcode },\n                query: Object.assign(Object.assign({}, query), { fields: (_a = query === null || query === void 0 ? void 0 : query.fields) === null || _a === void 0 ? void 0 : _a.join(\",\") }),\n            },\n        });\n        if (error != null) {\n            return { error, data: undefined };\n        }\n        return {\n            data: data,\n            error: undefined,\n        };\n    }\n}\n//# sourceMappingURL=off-v3.js.map","import { PRODUCT_IMAGE_URL, BackendType, BACKEND_DOMAINS, BACKEND_NAMES, } from \"./consts.js\";\nimport { Robotoff } from \"./robotoff.js\";\nimport { TAXONOMY_URL } from \"./taxonomy/api.js\";\nimport { ProductOpenerApiV2, getProductNameInLang, getProductIngredientsInLang, } from \"./off-v2.js\";\nimport { ProductOpenerApiV3 } from \"./off-v3.js\";\nexport { getProductNameInLang, getProductIngredientsInLang };\nimport { VERSION } from \"./version.js\";\n/** Wrapper of OFF API */\nexport class OpenFoodFacts {\n    /**\n     * Create OFF object\n     * @param fetch - Fetch implementation to use\n     * @param options - Options for the OFF Object\n     */\n    constructor(fetch, options = { country: \"world\", language: \"en\" }) {\n        ///////////\n        // API V2\n        ///////////\n        this.performOCR = (barcode, photoId, ocrEngine) => this.apiv2.performOCR(barcode, photoId, ocrEngine);\n        this.search = (query) => this.apiv2.search(query);\n        /**\n         * Returns all available attribute groups\n         * @returns A promise that resolves to an array of attribute groups\n         */\n        this.getAttributeGroups = () => this.apiv2.getAttributeGroups();\n        /**\n         * Returns product attributes for a given barcode\n         * @param barcode - The barcode of the product\n         * @returns A promise that resolves to an array of product attributes\n         */\n        this.getProductAttributes = (barcode) => this.apiv2.getProductAttributes(barcode);\n        /**\n         * Returns product details by barcode with optional fields\n         * @param barcode - The barcode of the product\n         * @param query - An optional query object to filter the returned fields\n         * @template T - An array of keys from ProductV3 to return\n         * @example\n         * ```typescript\n         * const result = await api.getProductV3(\"1234567890123\", { fields: [\"product_name\", \"brands\"] });\n         * console.log(result.product.product_name, result.product.brands);\n         * ```\n         * @returns A promise that resolves to a product object with the specified fields or undefined if not found\n         */\n        this.getProductV3 = (barcode, query) => this.apiv3.getProductV3(barcode, query);\n        /**\n         * Adds or edits a product using the V2 API\n         * @param product - The product data to add or edit\n         * @param credentials - Optional credentials for authentication\n         * @returns A promise that resolves to true if successful, false otherwise\n         */\n        this.addOrEditProductV2 = (product, credentials) => {\n            var _a, _b;\n            const username = (_a = credentials === null || credentials === void 0 ? void 0 : credentials.username) !== null && _a !== void 0 ? _a : this.defaultOptions.username;\n            const password = (_b = credentials === null || credentials === void 0 ? void 0 : credentials.password) !== null && _b !== void 0 ? _b : this.defaultOptions.password;\n            const nullableCredentials = username != null && password != null ? { username, password } : undefined;\n            return this.apiv2.addOrEditProductV2(product, nullableCredentials);\n        };\n        /**\n         * Uploads an image to OpenFoodFacts for a product.\n         * @param barcode - The barcode of the product\n         * @param imageFile - The image file to upload\n         * @param imagefield - The field name for the image (e.g., \"front\", \"ingredients\", \"nutrition\")\n         * @returns A promise that resolves to the upload response\n         */\n        this.uploadImage = (barcode, imageFile, imagefield) => this.apiv2.uploadImage(barcode, imageFile, imagefield);\n        /**\n         * Crops and selects an image for a product\n         * @param barcode - The barcode of the product\n         * @param imgid - Identifier of the image to select (should be a number)\n         * @param id - Identifier of the selected image field (format: {IMAGE_TYPE}_{LANG})\n         * @param cropData - Crop coordinates and options\n         * @returns A promise that resolves to the crop response\n         */\n        this.cropImage = (barcode, imgid, id, cropData) => this.apiv2.cropImage(barcode, imgid, id, cropData);\n        /**\n         * Rotates an image for a product\n         * @param barcode - The barcode of the product\n         * @param id - Identifier of the selected image field (format: {IMAGE_TYPE}_{LANG})\n         * @param imgid - Identifier of the image to rotate (should be a number as string)\n         * @param angle - Angle of rotation in degrees (90, 180, or 270 clockwise)\n         * @returns A promise that resolves to the rotation response\n         */\n        this.rotateImage = (barcode, id, imgid, angle) => this.apiv2.rotateImage(barcode, id, imgid, angle);\n        /**\n         * Unselects an image for a product\n         * @param barcode - The barcode of the product\n         * @param id - Image field (image id) of the photo to unselect (e.g., \"front_fr\")\n         * @returns A promise that resolves to the unselect response\n         */\n        this.unselectImage = (barcode, id) => this.apiv2.unselectImage(barcode, id);\n        /**\n         * Deletes an uploaded image for a product\n         * @param barcode - The barcode of the product corresponding to the image\n         * @param imgid - The id of the image to be deleted\n         * @returns A promise that resolves to the deletion response\n         */\n        this.deleteProductImage = (barcode, imgid) => this.apiv3.deleteProductImage(barcode, imgid);\n        /**\n         *\n         * @param barcode\n         * @param params\n         * @returns\n         */\n        this.uploadProductImage = (barcode, params) => this.apiv3.uploadProductImage(barcode, params);\n        /**\n         * Returns product data using the V2 API\n         * @param barcode - The barcode of the product\n         * @returns A promise that resolves to the product data or undefined if not found\n         */\n        this.getProductV2 = (barcode) => this.apiv2.getProductV2(barcode);\n        /**\n         * Returns an array of image names for the product\n         * @param barcode - The barcode of the product\n         * @returns A promise that resolves to an array of image names or null if not found\n         */\n        this.getProductImages = (barcode) => this.apiv2.getProductImages(barcode);\n        this.validateOptions(options);\n        this.backendType = options.type;\n        this.baseUrl = this.createBaseUrl(options);\n        this.customUserAgent = this.createUserAgent();\n        this.accessToken = options.accessToken;\n        this.fetch = this.createFetchWrapper(fetch, options);\n        this.defaultOptions = {\n            lang: options.language,\n            country: options.country,\n            username: undefined,\n            password: undefined,\n        };\n        this.apiv2 = new ProductOpenerApiV2(this.fetch, { host: this.baseUrl });\n        this.apiv3 = new ProductOpenerApiV3(this.fetch, { host: this.baseUrl });\n        this.robotoff = new Robotoff(fetch);\n    }\n    /**\n     * Validates constructor options for mutual exclusivity\n     */\n    validateOptions(options) {\n        if ((options.host && options.country) ||\n            (options.type && options.country)) {\n            throw new Error(\"You must provide either `host`, `type`, or `country`, not multiple.\");\n        }\n    }\n    /**\n     * Creates the base URL based on options\n     */\n    createBaseUrl(options) {\n        if (options.host != null) {\n            return options.host;\n        }\n        if (options.type != null) {\n            const domain = BACKEND_DOMAINS[options.type];\n            return `https://world.${domain}`;\n        }\n        return `https://${options.country || \"world\"}.openfoodfacts.org`;\n    }\n    /**\n     * Creates the User-Agent string based on backend type\n     */\n    createUserAgent() {\n        if (this.backendType != null) {\n            const backendName = BACKEND_NAMES[this.backendType];\n            return `${backendName} - NodeJS ${VERSION}`;\n        }\n        return `OpenFoodFacts - NodeJS ${VERSION}`;\n    }\n    /**\n     * Validates access token format and expiration\n     */\n    validateAccessToken(token) {\n        if (typeof token !== \"string\") {\n            throw new Error(\"Access token must be a string.\");\n        }\n        if (token.length === 0) {\n            throw new Error(\"Access token cannot be an empty string.\");\n        }\n        if (!/^[A-Za-z0-9-_.]+$/.test(token)) {\n            throw new Error(\"Access token can only contain alphanumeric characters, dashes, underscores, and periods.\");\n        }\n        if (this.isTokenExpired(token)) {\n            throw new Error(\"Access token is expired.\");\n        }\n    }\n    /**\n     * Creates a fetch wrapper with User-Agent and optional token handling\n     */\n    createFetchWrapper(fetch, options) {\n        // Base fetch wrapper with User-Agent\n        let wrappedFetch = this.createUserAgentFetch(fetch);\n        // Add token handling if access token is provided\n        if (options.accessToken != null) {\n            this.validateAccessToken(options.accessToken);\n            wrappedFetch = this.createTokenAwareFetch(wrappedFetch, options);\n        }\n        return wrappedFetch;\n    }\n    /**\n     * Creates a fetch wrapper that adds User-Agent header\n     */\n    createUserAgentFetch(fetch) {\n        return (url, init) => {\n            const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n            headers.set(\"User-Agent\", this.customUserAgent);\n            return fetch(url, Object.assign(Object.assign({}, init), { headers }));\n        };\n    }\n    /**\n     * Creates a fetch wrapper that handles token refresh and authorization\n     */\n    createTokenAwareFetch(fetch, options) {\n        return async (url, init) => {\n            const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n            if (this.accessToken == null) {\n                throw new Error(\"Access token was first specified and now is null.\");\n            }\n            if (this.isTokenExpired(this.accessToken)) {\n                this.accessToken = await this.refreshAccessToken(options);\n            }\n            headers.set(\"Authorization\", `Bearer ${this.accessToken}`);\n            return fetch(url, Object.assign(Object.assign({}, init), { headers }));\n        };\n    }\n    /**\n     * Refreshes the access token using the provided callback\n     */\n    async refreshAccessToken(options) {\n        if (options.onAccessTokenExpired == null) {\n            throw new Error(\"Access token expired and no handler provided to refresh it.\" +\n                \" You should provide `onAccessTokenExpired` option or wrap the fetch function to handle token expiration.\");\n        }\n        const newAccessToken = await options.onAccessTokenExpired();\n        if (newAccessToken == null) {\n            throw new Error(\"onAccessTokenExpired handler did not return a new access token.\");\n        }\n        return newAccessToken;\n    }\n    isTokenExpired(token) {\n        const parts = token.split(\".\");\n        if (parts.length !== 3) {\n            throw new Error(\"Invalid JWT token format\");\n        }\n        const payload = JSON.parse(Buffer.from(parts[1], \"base64\").toString(\"utf-8\"));\n        // Check if the token is expired\n        return payload.exp && Date.now() >= payload.exp * 1000;\n    }\n    ////////////////\n    // TAXONOMIES\n    ////////////////\n    getBrand(brandName) {\n        return this.apiv2.getTaxoEntry(\"brands\", brandName);\n    }\n    getLanguage(languageName) {\n        return this.apiv2.getTaxoEntry(\"languages\", languageName);\n    }\n    getBrands() {\n        return this.getTaxo(\"brands\");\n    }\n    getLanguages() {\n        return this.getTaxo(\"languages\");\n    }\n    getLabels() {\n        return this.getTaxo(\"labels\");\n    }\n    getAdditives() {\n        return this.getTaxo(\"additives\");\n    }\n    getAllergens() {\n        return this.getTaxo(\"allergens\");\n    }\n    getCategories() {\n        return this.getTaxo(\"categories\");\n    }\n    getCountries() {\n        return this.getTaxo(\"countries\");\n    }\n    getIngredients() {\n        return this.getTaxo(\"ingredients\");\n    }\n    getPackagings() {\n        return this.getTaxo(\"packaging\");\n    }\n    getStates() {\n        return this.getTaxo(\"states\");\n    }\n    getStores() {\n        return this.getTaxo(\"stores\");\n    }\n    getNutrients() {\n        return this.getTaxo(\"nutrients\");\n    }\n    async getTaxo(taxo) {\n        const res = await this.fetch(TAXONOMY_URL(taxo));\n        return (await res.json());\n    }\n    async getFacet(facet, opts) {\n        const params = new URLSearchParams();\n        if (opts === null || opts === void 0 ? void 0 : opts.page)\n            params.set(\"page\", `${opts.page}`);\n        if (opts === null || opts === void 0 ? void 0 : opts.pageSize)\n            params.set(\"page_size\", `${opts.pageSize}`);\n        if (opts === null || opts === void 0 ? void 0 : opts.sortBy)\n            params.set(\"sort_by\", opts.sortBy);\n        const res = await this.fetch(`${this.baseUrl}/facets/${facet}.json?${params}`);\n        return (await res.json());\n    }\n    async getFacetValue(facet, value, opts) {\n        const params = new URLSearchParams();\n        if (opts === null || opts === void 0 ? void 0 : opts.page)\n            params.set(\"page\", `${opts.page}`);\n        if (opts === null || opts === void 0 ? void 0 : opts.pageSize)\n            params.set(\"page_size\", `${opts.pageSize}`);\n        if (opts === null || opts === void 0 ? void 0 : opts.sortBy)\n            params.set(\"sort_by\", opts.sortBy);\n        const res = await this.fetch(new URL(`${this.baseUrl}/facets/${facet}/${value}.json?${params}`));\n        return (await res.json());\n    }\n    async getLoginStatus() {\n        const response = await this.fetch(new URL(\"/cgi/auth.pl?body=1\", this.baseUrl));\n        if (!response.ok)\n            return undefined;\n        return (await response.json());\n    }\n}\nexport default OpenFoodFacts;\n/**\n * Gets URL for a product image based on its barcode and image name\n * @param barcode - Product barcode\n * @param imageName - Name of the image (e.g., \"front\", \"ingredients\", \"nutrition\")\n * @param images - Image metadata from product data\n * @param size - Image size (100, 200, 400, or full) - defaults to 400\n * @returns Complete URL to the specific image or null if not found\n */\nexport function getProductImageUrl(barcode, imageName, images, size = \"400\") {\n    const paddedBarcode = barcode.toString().padStart(13, \"0\");\n    const match = paddedBarcode.match(/^(.{3})(.{3})(.{3})(.*)$/);\n    if (!match) {\n        throw new Error(`Invalid barcode format: ${paddedBarcode}`);\n    }\n    const path = `${match[1]}/${match[2]}/${match[3]}/${match[4]}`;\n    const image = images[imageName];\n    if (!image) {\n        return null;\n    }\n    const rev = image.rev;\n    let filename;\n    if (rev) {\n        filename = `${imageName}.${rev}.${size}.jpg`;\n    }\n    else {\n        filename = `${imageName}.${size}.jpg`;\n    }\n    return PRODUCT_IMAGE_URL(`${path}/${filename}`);\n}\n//# sourceMappingURL=off.js.map","import { addParamsToUrl } from \"../utils\"\nimport {\n  type QuestionRequestParams,\n  type QuestionsResponse,\n  AnnotationAnswer,\n  type InsightsRequestParams,\n  type InsightsResponse,\n  type NutrientsInsight,\n  type IngredientSpellcheckInsight,\n  type NutrientsAnnotationData,\n  type IngredientDetectionInsight,\n  type IngredientDetectionAnnotationData,\n  InsightType,\n} from \"../types/robotoff\"\nimport { robotoffConfiguration } from \"../signals/robotoff\"\nimport { languageCode } from \"../signals/app\"\n\nimport { Robotoff } from \"@openfoodfacts/openfoodfacts-nodejs\"\n\nfunction createRobotoff(fetch: typeof window.fetch) {\n  // ensure that any user account credentials get used in Robotoff\n  const fetchWithCredentials: typeof window.fetch = (url, options) => {\n    return fetch(url, { ...options, credentials: \"include\" })\n  }\n  return new Robotoff(fetchWithCredentials, {\n    baseUrl: robotoffConfiguration.getItem(\"apiUrl\") as string,\n  })\n}\n\n/**\n * Get the API URL for a given path with the current configuration\n */\nconst getApiUrl = (path: string) => {\n  return `${robotoffConfiguration.getItem(\"apiUrl\")}${path}`\n}\n\n/**\n * Annotate an insight\n * @param formBody\n * @returns {Promise<Response>}\n */\nconst annotate = (formBody: string) => {\n  const apiUrl = getApiUrl(\"/insights/annotate\")\n  if (robotoffConfiguration.getItem(\"dryRun\")) {\n    console.log(\"Annotated :\", apiUrl, formBody)\n    return\n  } else {\n    return fetch(apiUrl, {\n      method: \"POST\",\n      body: formBody,\n      headers: {\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n      },\n      credentials: \"include\",\n    })\n  }\n}\n\n/**\n * Robotoff API\n */\nconst robotoff = {\n  annotate,\n  annotateQuestion(insightId: string, annotation: AnnotationAnswer) {\n    const robotoff = createRobotoff(fetch)\n    return robotoff.annotate({ insight_id: insightId, annotation: annotation })\n  },\n  annotateNutrients(\n    insightId: string,\n    annotation: AnnotationAnswer,\n    data?: NutrientsAnnotationData\n  ) {\n    const newLocal = createRobotoff(fetch)\n    return newLocal.annotate({ insight_id: insightId, annotation: annotation, data: data })\n  },\n\n  /**\n   * Annotate an insight\n   * @param insightId The insight id\n   * @param annotation The annotation answer ${QuestionAnnotationAnswer}\n   * @param correction The correction given by the user if the correction is different\n   * from the one proposed by the insight or the original one\n   */\n  annotateIngredientSpellcheck(\n    insightId: string,\n    annotation: AnnotationAnswer,\n    correction?: string\n  ) {\n    return createRobotoff(fetch).annotate({\n      insight_id: insightId,\n      annotation: annotation,\n      ...(correction ? { data: { annotation: correction } } : {}),\n    })\n  },\n\n  /**\n   * Annotate an insight\n   * @param insightId The insight id\n   * @param annotation The annotation answer ${QuestionAnnotationAnswer}\n   * @param data The data to send to the API\n   */\n  annotateIngredientDetection(\n    insightId: string,\n    annotation: AnnotationAnswer,\n    data?: IngredientDetectionAnnotationData\n  ) {\n    return createRobotoff(fetch).annotate({\n      insight_id: insightId,\n      annotation: annotation,\n      ...(data ? { data: data } : {}),\n    })\n  },\n\n  /**\n   * Get questions by product code\n   * @param code The product code\n   * @param questionRequestParams The request params\n   * @returns {Promise<QuestionsResponse>}\n   */\n  async questionsByProductCode(\n    code: string,\n    questionRequestParams: QuestionRequestParams = {}\n  ): Promise<QuestionsResponse> {\n    if (!questionRequestParams.lang) {\n      questionRequestParams.lang = languageCode.get()\n    }\n    const apiUrl = getApiUrl(`/questions/${code}`)\n    const url = addParamsToUrl(apiUrl, questionRequestParams)\n    // Note: we need credentials to be sure to have all questions\n    const response = await fetch(url, { credentials: \"include\" })\n    const result: QuestionsResponse = await response.json()\n    return result\n  },\n\n  /**\n   * Get insights\n   * @param requestParams The request params\n   * @returns The insights response. Currently only ingredients and\n   * nutrients insights are supported\n   */\n  async insights<\n    T extends NutrientsInsight | IngredientSpellcheckInsight | IngredientDetectionInsight,\n  >(requestParams: InsightsRequestParams = {}): Promise<InsightsResponse<T>> {\n    const apiUrl = getApiUrl(\"/insights\")\n    const url = addParamsToUrl(apiUrl, requestParams)\n    // Note: we need credentials to be sure to have all insights\n    const response = await fetch(url, { credentials: \"include\" })\n    const result: InsightsResponse<T> = await response.json()\n    return result\n  },\n\n  /**\n   * Get insights for the robotoff contribution message\n   * Reduces the number of calls to the API by fetching multiple insights at once\n   * @param requestParams The request params\n   * @returns {Promise<InsightsResponse>} The insights response, currently only\n   * ingredients and nutrients insights are supported\n   */\n  async fetchRobotoffContributionMessageInsights(\n    requestParams: InsightsRequestParams = {}\n  ): Promise<Array<NutrientsInsight | IngredientSpellcheckInsight | IngredientDetectionInsight>> {\n    const result = await this.insights<\n      NutrientsInsight | IngredientSpellcheckInsight | IngredientDetectionInsight\n    >({\n      ...requestParams,\n      annotated: false,\n      insight_types: [\n        InsightType.nutrient_extraction,\n        InsightType.ingredient_spellcheck,\n        InsightType.ingredient_detection,\n      ],\n    })\n    return result.insights\n  },\n}\n\nexport default robotoff\n","import { Computed } from \"@lit-labs/signals\"\nimport robotoff from \"../api/robotoff\"\nimport { type Question, AnnotationAnswer, type QuestionRequestParams } from \"../types/robotoff\"\nimport { SignalMap } from \"../utils/signals\"\n\n// Store questions by id\nexport const questionsById = new SignalMap<Question>({})\n\n// Store question ids by product code\nexport const questionIdsByProductCode = new SignalMap<string[]>({})\n\n// Current question index by product code\nexport const currentQuestionIndexByProductCode = new SignalMap<number>({})\n\n// Is questions finished by product code\nexport const isQuestionsFinishedByProductCode = new SignalMap<boolean>({})\n\n// Get questions by product code\nexport const questions = (productCode: string) =>\n  new Computed(() => {\n    return questionIdsByProductCode.get()[productCode].map((id) => questionsById.getItem(id))\n  })\n\n// Get current question index by product code\nexport const currentQuestionIndex = (productCode: string) =>\n  new Computed(() => {\n    return currentQuestionIndexByProductCode.getItem(productCode) ?? 0\n  })\n/** Does the current product has questions */\nexport const hasQuestions = (productCode: string) =>\n  new Computed(() => questionIdsByProductCode.getItem(productCode)?.length > 0)\n/** Number of questions available */\nexport const numberOfQuestions = (productCode: string) =>\n  new Computed(() => questionIdsByProductCode.getItem(productCode)?.length ?? 0)\n/** Indicates if all questions have been answered */\nexport const isQuestionsFinished = (productCode: string) =>\n  new Computed(() => isQuestionsFinishedByProductCode.getItem(productCode) ?? false)\n\n/**\n * Fetches questions for a given product code.\n * @param code - The product code.\n * @param params - Additional parameters for the question request.\n */\nexport const fetchQuestionsByProductCode = async (\n  code: string,\n  params: QuestionRequestParams = {}\n): Promise<Question[]> => {\n  isQuestionsFinishedByProductCode.setItem(code, false)\n  currentQuestionIndexByProductCode.setItem(code, 0)\n  questionIdsByProductCode.setItem(code, [])\n  const response = await robotoff.questionsByProductCode(code, params)\n\n  questionIdsByProductCode.setItem(\n    code,\n    response.questions?.map((question) => question.insight_id) ?? []\n  )\n\n  response.questions?.forEach((question: Question) => {\n    questionsById.setItem(question.insight_id, question)\n  })\n\n  return response.questions ?? []\n}\n\n/**\n * Checks if all questions have been answered.\n * @returns True if all questions have been answered, otherwise false.\n */\nexport const checkIfQuestionsFinishedByProductCode = (productCode: string) => {\n  const current = currentQuestionIndex(productCode).get()\n  const count = numberOfQuestions(productCode).get()\n\n  if (current === count) {\n    isQuestionsFinishedByProductCode.setItem(productCode, true)\n    return true\n  }\n  return false\n}\n\n/**\n * Answers a question.\n * @param insightId - The ID of the insight.\n * @param value - The answer to the question.\n */\nexport const answerQuestion = async (insightId: string, value: AnnotationAnswer) => {\n  await robotoff.annotateQuestion(insightId, value)\n}\n\n/**\n * Moves to the next question.\n * @returns False if all questions have been answered, otherwise true.\n */\nexport const nextQuestionByProductCode = (productCode: string) => {\n  const current = currentQuestionIndex(productCode).get()\n  currentQuestionIndexByProductCode.setItem(productCode, current + 1)\n  if (checkIfQuestionsFinishedByProductCode(productCode)) {\n    return false\n  }\n  return true\n}\n","import{notEqual as t}from\"@lit/reactive-element\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const s={INITIAL:0,PENDING:1,COMPLETE:2,ERROR:3},i=Symbol();class h{get taskComplete(){return this.t||(1===this.i?this.t=new Promise(((t,s)=>{this.o=t,this.h=s})):3===this.i?this.t=Promise.reject(this.l):this.t=Promise.resolve(this.u)),this.t}constructor(t,s,i){this.p=0,this.i=0,(this._=t).addController(this);const h=\"object\"==typeof s?s:{task:s,args:i};this.v=h.task,this.j=h.args,this.m=h.argsEqual??r,this.k=h.onComplete,this.A=h.onError,this.autoRun=h.autoRun??!0,\"initialValue\"in h&&(this.u=h.initialValue,this.i=2,this.O=this.T?.())}hostUpdate(){!0===this.autoRun&&this.S()}hostUpdated(){\"afterUpdate\"===this.autoRun&&this.S()}T(){if(void 0===this.j)return;const t=this.j();if(!Array.isArray(t))throw Error(\"The args function must return an array\");return t}async S(){const t=this.T(),s=this.O;this.O=t,t===s||void 0===t||void 0!==s&&this.m(s,t)||await this.run(t)}async run(t){let s,h;t??=this.T(),this.O=t,1===this.i?this.q?.abort():(this.t=void 0,this.o=void 0,this.h=void 0),this.i=1,\"afterUpdate\"===this.autoRun?queueMicrotask((()=>this._.requestUpdate())):this._.requestUpdate();const r=++this.p;this.q=new AbortController;let e=!1;try{s=await this.v(t,{signal:this.q.signal})}catch(t){e=!0,h=t}if(this.p===r){if(s===i)this.i=0;else{if(!1===e){try{this.k?.(s)}catch{}this.i=2,this.o?.(s)}else{try{this.A?.(h)}catch{}this.i=3,this.h?.(h)}this.u=s,this.l=h}this._.requestUpdate()}}abort(t){1===this.i&&this.q?.abort(t)}get value(){return this.u}get error(){return this.l}get status(){return this.i}render(t){switch(this.i){case 0:return t.initial?.();case 1:return t.pending?.();case 2:return t.complete?.(this.value);case 3:return t.error?.(this.error);default:throw Error(\"Unexpected status: \"+this.i)}}}const r=(s,i)=>s===i||s.length===i.length&&s.every(((s,h)=>!t(s,i[h])));export{h as Task,s as TaskStatus,i as initialState,r as shallowArrayEquals};\n//# sourceMappingURL=task.js.map\n","import { localized, msg } from \"@lit/localize\"\nimport { html, LitElement } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n\n/**\n * A simple loader component. It allows to display a same loader in different components.\n * @element off-wc-loader\n **/\n@customElement(\"off-wc-loader\")\n@localized()\nexport class OffWcLoader extends LitElement {\n  override render() {\n    return html` <div>${msg(\"Loading...\")}</div> `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"off-wc-loader\": OffWcLoader\n  }\n}\n","import { unsafeCSS } from \"lit\"\n\nexport const DARKER_WHITE = \"#fafafa\"\nexport const LIGHT_BLACK = \"rgba(0, 0, 0, 0.75)\"\nexport const CHOCOLATE = \"#341100\"\nexport const CAPPUCINO = \"#ede0db\"\nexport const LIGHT_GREY = \"#f0f0f0\"\nexport const GREY = \"#ccc\"\nexport const BLUE = \"#0064c8\"\nexport const SUCCESS = \"#8BC34A\"\nexport const DANGER = \"#FF5252\"\nexport const LIGHT_RED = \"#ffcccc\"\nexport const LIGHT_GREEN = \"#ccffcc\"\nexport const GREEN = \"#199654\"\n\nexport const SAFE_DARKER_WHITE = unsafeCSS(DARKER_WHITE)\nexport const SAFE_LIGHT_BLACK = unsafeCSS(LIGHT_BLACK)\nexport const SAFE_CHOCOLATE = unsafeCSS(CHOCOLATE)\nexport const SAFE_CAPPUCINO = unsafeCSS(CAPPUCINO)\nexport const SAFE_LIGHT_GREY = unsafeCSS(LIGHT_GREY)\nexport const SAFE_GREY = unsafeCSS(GREY)\nexport const SAFE_BLUE = unsafeCSS(BLUE)\nexport const SAFE_SUCCESS = unsafeCSS(SUCCESS)\nexport const SAFE_DANGER = unsafeCSS(DANGER)\nexport const SAFE_LIGHT_RED = unsafeCSS(LIGHT_RED)\nexport const SAFE_LIGHT_GREEN = unsafeCSS(LIGHT_GREEN)\nexport const SAFE_GREEN = unsafeCSS(GREEN)\n","import { css, type CSSResult } from \"lit-element\"\nimport {\n  SAFE_CAPPUCINO,\n  SAFE_CHOCOLATE,\n  SAFE_DANGER,\n  SAFE_LIGHT_GREEN,\n  SAFE_LIGHT_RED,\n  SAFE_SUCCESS,\n} from \"../utils/colors\"\n\nexport enum ButtonType {\n  Chocolate = \"chocolate\",\n  Cappucino = \"cappucino\",\n  ChocolateOutline = \"chocolate-outline\",\n  White = \"white\",\n  LINK = \"link\",\n  Success = \"success\",\n  Danger = \"danger\",\n  LightRed = \"light-red\",\n  LightGreen = \"light-green\",\n}\n\nexport const getDefaultButtonClasses = (): CSSResult => {\n  return css`\n    .buttons-row {\n      display: flex;\n      gap: 0.5rem;\n    }\n\n    .buttons-row.can-wrap {\n      flex-wrap: wrap;\n    }\n\n    .button {\n      padding: 0.5rem 1rem;\n      border-radius: 0.25rem;\n      font-size: 1rem;\n      border-width: 1px;\n      border-style: solid;\n      cursor: pointer;\n    }\n\n    .button .pre-wrap {\n      white-space: pre-wrap;\n    }\n    .button.rounded {\n      border-radius: 50%;\n    }\n\n    .button:focus {\n      outline: 1px solid black;\n      outline-offset: 4px;\n    }\n\n    .button.small {\n      padding: 0.25rem 0.5rem;\n      font-size: 0.875rem;\n    }\n\n    .button.with-icon {\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n    }\n    .button:disabled {\n      cursor: not-allowed;\n      opacity: 0.5;\n    }\n  `\n}\n\nexport const BUTTON_CLASS_BY_TYPE: Record<ButtonType, CSSResult> = {\n  [ButtonType.Chocolate]: css`\n    .chocolate-button {\n      background-color: ${SAFE_CHOCOLATE};\n      border-color: ${SAFE_CHOCOLATE};\n      color: white;\n    }\n\n    .chocolate-button:hover {\n      background-color: white;\n      color: ${SAFE_CHOCOLATE};\n    }\n  `,\n  [ButtonType.Cappucino]: css`\n    .cappucino-button {\n      background-color: ${SAFE_CAPPUCINO};\n      border-color: ${SAFE_CAPPUCINO};\n      color: black;\n    }\n\n    .cappucino-button:hover {\n      background-color: white;\n    }\n  `,\n  [ButtonType.ChocolateOutline]: css`\n    .chocolate-button-outline {\n      background-color: transparent;\n      border-color: ${SAFE_CHOCOLATE};\n      color: ${SAFE_CHOCOLATE};\n    }\n\n    .chocolate-button-outline:hover {\n      background-color: ${SAFE_CHOCOLATE};\n      color: white;\n    }\n  `,\n  [ButtonType.White]: css`\n    .white-button {\n      background-color: white;\n      border-color: white;\n      color: black;\n    }\n\n    .white-button:hover {\n      border-color: black;\n      background-color: black;\n      color: white;\n    }\n  `,\n  [ButtonType.LINK]: css`\n    .link-button {\n      text-decoration: none;\n      background-color: transparent;\n      border-color: transparent;\n      cursor: pointer;\n      color: black;\n    }\n\n    .link-button:hover {\n      text-decoration: underline;\n    }\n  `,\n  [ButtonType.Success]: css`\n    .success-button {\n      background-color: ${SAFE_SUCCESS};\n      border-color: ${SAFE_SUCCESS};\n      color: white;\n    }\n    .success-button:hover {\n      background-color: white;\n      color: ${SAFE_SUCCESS};\n    }\n  `,\n  [ButtonType.Danger]: css`\n    .danger-button {\n      background-color: ${SAFE_DANGER};\n      border-color: ${SAFE_DANGER};\n      color: white;\n    }\n    .danger-button:hover {\n      background-color: white;\n      color: ${SAFE_DANGER};\n    }\n  `,\n  [ButtonType.LightRed]: css`\n    .light-red-button {\n      background-color: ${SAFE_LIGHT_RED};\n      border-color: ${SAFE_LIGHT_RED};\n      color: black;\n    }\n    .light-red-button:hover {\n      background-color: white;\n      color: ${SAFE_DANGER};\n    }\n  `,\n  [ButtonType.LightGreen]: css`\n    .light-green-button {\n      background-color: ${SAFE_LIGHT_GREEN};\n      border-color: ${SAFE_LIGHT_GREEN};\n      color: black;\n    }\n    .light-green-button:hover {\n      background-color: white;\n      color: ${SAFE_SUCCESS};\n      border-color: ${SAFE_SUCCESS};\n    }\n  `,\n}\n\nexport const getButtonClasses = (types: ButtonType[]): CSSResult[] => {\n  const buttonClasses = [getDefaultButtonClasses()]\n\n  types.forEach((type) => {\n    buttonClasses.push(BUTTON_CLASS_BY_TYPE[type])\n  })\n  return buttonClasses\n}\n","import type { Constructor } from \".\"\nimport { LitElement } from \"lit\"\nimport { state } from \"lit/decorators.js\"\n\n/**\n * Interface for the LoadingMixin.\n */\nexport interface LoadingMixinInterface<L> {\n  startTime?: number\n  loading: L | undefined\n  showLoading(message: L): void\n  hideLoading(): void\n}\n\nconst DURATION = 750\n\n/**\n * Mixin that adds loading functionality to a LitElement.\n * It will show the loading state for at least 750ms to avoid flickering.\n */\nexport const LoadingWithTimeoutMixin = <L, T extends Constructor<LitElement>>(\n  superClass: T,\n  initialLoading: L | undefined\n): Constructor<LoadingMixinInterface<L>> & T => {\n  class LoadingWithTimeoutMixinClass extends superClass {\n    /**\n     * Indicates the loading state of the component.\n     * Can be undefined or a string value.\n     */\n    @state()\n    loading: L | undefined = initialLoading\n\n    /**\n     * The time when the loading state started.\n     */\n    startTime?: number\n\n    /**\n     * Shows the loading state with a specific message\n     * @param loading - The loading to display\n     */\n    showLoading(loading: L) {\n      this.startTime = Date.now()\n      this.loading = loading\n    }\n\n    /**\n     * Hides the loading state\n     */\n    async hideLoading() {\n      const timeElapsed = Date.now() - (this.startTime ?? 0)\n      const timeoutTime = Math.max(0, DURATION - timeElapsed)\n      await new Promise((resolve) => {\n        setTimeout(() => {\n          this.loading = undefined\n          resolve(undefined)\n        }, timeoutTime)\n      })\n    }\n  }\n  return LoadingWithTimeoutMixinClass as Constructor<LoadingMixinInterface<L>> & T\n}\n","import { css } from \"lit\"\n\nexport const RELATIVE = css`\n  .relative {\n    position: relative;\n  }\n`\nexport const FLEX = css`\n  .flex {\n    display: flex;\n  }\n  .flex-col {\n    flex-direction: column;\n  }\n  .justify-center {\n    justify-content: center;\n  }\n  .justify-between {\n    justify-content: space-between;\n  }\n  .justify-end {\n    justify-content: flex-end;\n  }\n  .flex-wrap {\n    flex-wrap: wrap;\n  }\n  .align-center {\n    align-items: center;\n  }\n  .gap-0_5 {\n    gap: 0.5rem;\n  }\n  .gap-1 {\n    gap: 1rem;\n  }\n`\n\nexport const IS_HIDDEN = css`\n  .is-hidden {\n    display: none;\n  }\n`\n\nexport const FULL_WIDTH = css`\n  .full-width {\n    width: 100%;\n  }\n`\n","import { LitElement, html, css } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\n\n@customElement(\"loading-spin\")\nexport class LoadingSpin extends LitElement {\n  @property({ type: String }) size: string = \"24px\"\n  @property({ type: String }) color: string = \"currentColor\"\n\n  static override styles = css`\n    :host {\n      display: inline-flex;\n    }\n\n    .spinner {\n      animation: spin 1s linear infinite;\n    }\n\n    @keyframes spin {\n      from {\n        transform: rotate(0deg);\n      }\n      to {\n        transform: rotate(360deg);\n      }\n    }\n  `\n\n  override render() {\n    return html`\n      <svg\n        width=${this.size}\n        height=${this.size}\n        viewBox=\"0 0 16 16\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        fill=\"none\"\n        class=\"spinner\"\n      >\n        <g fill=${this.color} fill-rule=\"evenodd\" clip-rule=\"evenodd\">\n          <path\n            d=\"M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8z\"\n            opacity=\".2\"\n          />\n\n          <path\n            d=\"M7.25.75A.75.75 0 018 0a8 8 0 018 8 .75.75 0 01-1.5 0A6.5 6.5 0 008 1.5a.75.75 0 01-.75-.75z\"\n          />\n        </g>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"loading-spin\": LoadingSpin\n  }\n}\n","import { html, css, LitElement, nothing } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport \"../icons/loading-spin\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\n\n/**\n * A button component that shows a loading spinner when in a loading state.\n * @fire click - Fired when the button is clicked\n * @slot - This element has a slot for custom content\n */\n@customElement(\"loading-button\")\nexport class LoadingButton extends LitElement {\n  static override styles = [\n    css`\n      :host {\n        display: inline-block;\n      }\n      button {\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        width: 100%;\n        gap: 0.5rem;\n      }\n    `,\n    ...getButtonClasses(Object.values(ButtonType)),\n  ]\n\n  /**\n   * The text to display on the button\n   */\n  @property({ type: String, reflect: true })\n  label = \"\"\n\n  /**\n   * Whether the button is in a loading state\n   */\n  @property({ type: Boolean, reflect: true })\n  loading = false\n\n  /**\n   * Whether the button is disabled\n   */\n  @property({ type: Boolean, reflect: true })\n  disabled = false\n\n  /**\n   * Additional CSS classes to apply to the button\n   */\n  @property({ type: String, attribute: \"css-classes\" })\n  cssClasses = \"\"\n\n  /**\n   * The type of the button (button, submit, reset)\n   */\n  @property({ type: String })\n  type: \"button\" | \"submit\" | \"reset\" = \"button\"\n\n  override render() {\n    return html`\n      <button\n        type=${this.type}\n        class=\"${this.cssClasses}\"\n        ?disabled=${this.disabled || this.loading}\n        ?loading=${this.loading}\n      >\n        ${this.loading ? html`<loading-spin size=\"15px\"></loading-spin>` : nothing}\n        <slot><span>${this.label}</span></slot>\n      </button>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"loading-button\": LoadingButton\n  }\n}\n","import { LitElement, html, css } from \"lit-element\"\nimport { customElement } from \"lit/decorators.js\"\n\n/**\n * Component that displays a zoom icon.\n * @element zoom-icon\n **/\n@customElement(\"zoom-icon\")\nexport class ZoomIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 24px;\n      height: 24px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n\n  override connectedCallback() {\n    super.connectedCallback()\n  }\n\n  override render() {\n    return html`\n      <svg\n        width=\"800px\"\n        height=\"800px\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <path\n          d=\"M10 17C13.866 17 17 13.866 17 10C17 6.13401 13.866 3 10 3C6.13401 3 3 6.13401 3 10C3 13.866 6.13401 17 10 17Z\"\n          stroke=\"#000000\"\n          stroke-width=\"1.5\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n        />\n        <path\n          d=\"M20.9992 21L14.9492 14.95\"\n          stroke=\"#000000\"\n          stroke-width=\"1.5\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n        />\n        <path\n          d=\"M6 10H14\"\n          stroke=\"#000000\"\n          stroke-width=\"1.5\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n        />\n        <path\n          d=\"M10 6V14\"\n          stroke=\"#000000\"\n          stroke-width=\"1.5\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n        />\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"zoom-icon\": ZoomIcon\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n/**\n * Component that displays a unzoom icon.\n * @element unzoom-icon\n **/\n@customElement(\"unzoom-icon\")\nexport class UnzoomIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 24px;\n      height: 24px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n\n  override render() {\n    return html`\n      <svg\n        width=\"800px\"\n        height=\"800px\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <path\n          d=\"M10 17C13.866 17 17 13.866 17 10C17 6.13401 13.866 3 10 3C6.13401 3 3 6.13401 3 10C3 13.866 6.13401 17 10 17Z\"\n          stroke=\"#000000\"\n          stroke-width=\"1.5\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n        />\n        <path\n          d=\"M20.9992 21L14.9492 14.95\"\n          stroke=\"#000000\"\n          stroke-width=\"1.5\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n        />\n        <path\n          d=\"M6 10H14\"\n          stroke=\"#000000\"\n          stroke-width=\"1.5\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"\n        />\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"unzoom-icon\": UnzoomIcon\n  }\n}\n","import { localized, msg } from \"@lit/localize\"\nimport { LitElement, html, css } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { SAFE_LIGHT_GREY } from \"../../utils/colors\"\nimport \"../icons/zoom\"\nimport \"../icons/unzoom\"\n\n/**\n * @element zoom-unzoom-button\n * @fires click - Fired when the button is clicked\n */\n@customElement(\"zoom-unzoom-button\")\n@localized()\nexport class ZoomUnzoomButton extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n    }\n    button {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      background-color: white;\n      border: none;\n      border-radius: 50%;\n      width: 26px;\n      height: 26px;\n      cursor: pointer;\n    }\n    button:hover {\n      background-color: ${SAFE_LIGHT_GREY};\n    }\n  `\n\n  @property({ type: Boolean })\n  zoomed = false\n\n  override render() {\n    return html`\n      <button title=${this.zoomed ? msg(\"Unzoom\") : msg(\"Zoom\")}>\n        ${this.zoomed ? html`<unzoom-icon></unzoom-icon>` : html`<zoom-icon></zoom-icon>`}\n      </button>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"zoom-unzoom-button\": ZoomUnzoomButton\n  }\n}\n","import{noChange as t}from\"../lit-html.js\";import{directive as e,Directive as r,PartType as s}from\"../directive.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const n=\"important\",i=\" !\"+n,o=e(class extends r{constructor(t){if(super(t),t.type!==s.ATTRIBUTE||\"style\"!==t.name||t.strings?.length>2)throw Error(\"The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.\")}render(t){return Object.keys(t).reduce(((e,r)=>{const s=t[r];return null==s?e:e+`${r=r.includes(\"-\")?r:r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,\"-$&\").toLowerCase()}:${s};`}),\"\")}update(e,[r]){const{style:s}=e.element;if(void 0===this.ft)return this.ft=new Set(Object.keys(r)),this.render(r);for(const t of this.ft)null==r[t]&&(this.ft.delete(t),t.includes(\"-\")?s.removeProperty(t):s[t]=null);for(const t in r){const e=r[t];if(null!=e){this.ft.add(t);const r=\"string\"==typeof e&&e.endsWith(i);t.includes(\"-\")||r?s.setProperty(t,r?e.slice(0,-11):e,r?n:\"\"):s[t]=e}}return t}});export{o as styleMap};\n//# sourceMappingURL=style-map.js.map\n","import { LitElement, html, css } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n\n/**\n * Rotate left icon\n */\n@customElement(\"rotate-left-icon\")\nclass RotateLeftIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 24px;\n      height: 24px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n\n  override render() {\n    return html`\n      <svg focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\">\n        <path\n          d=\"M7.11 8.53 5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z\"\n        ></path>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"rotate-left-icon\": RotateLeftIcon\n  }\n}\n","import { css, LitElement } from \"lit\"\nimport { html } from \"lit-html\"\nimport { customElement } from \"lit/decorators.js\"\n\n/**\n * Rotate right icon\n */\n@customElement(\"rotate-right-icon\")\nexport class RotateRightIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 24px;\n      height: 24px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n  override render() {\n    return html`\n      <svg focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\">\n        <path\n          d=\"M15.55 5.55 11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42 1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z\"\n        ></path>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"rotate-right-icon\": RotateRightIcon\n  }\n}\n","// Inspire from https://bulma.io/documentation/start/responsiveness/#breakpoints\nexport enum Breakpoints {\n  XS = 425,\n  SM = 768,\n  MD = 1024,\n  LG = 1216,\n  XL = 1408,\n}\n\n// https://stackoverflow.com/questions/11381673/detecting-a-mobile-browser\nexport const mobileAndTabletRegex =\n  /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk|1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|ch\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i\n\n/**\n * Mobile and tablet check.\n * @returns {boolean} True if the device is a mobile or tablet, false otherwise.\n */\nexport const mobileAndTabletCheck = () => {\n  const value = navigator.userAgent || navigator.vendor || (window as any).opera\n\n  return mobileAndTabletRegex.test(value) || mobileAndTabletRegex.test(value.substr(0, 4))\n}\n","const IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';\nconst WINDOW = IS_BROWSER ? window : {};\nconst IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;\nconst HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;\nconst NAMESPACE = 'cropper';\nconst CROPPER_CANVAS = `${NAMESPACE}-canvas`;\nconst CROPPER_CROSSHAIR = `${NAMESPACE}-crosshair`;\nconst CROPPER_GIRD = `${NAMESPACE}-grid`;\nconst CROPPER_HANDLE = `${NAMESPACE}-handle`;\nconst CROPPER_IMAGE = `${NAMESPACE}-image`;\nconst CROPPER_SELECTION = `${NAMESPACE}-selection`;\nconst CROPPER_SHADE = `${NAMESPACE}-shade`;\nconst CROPPER_VIEWER = `${NAMESPACE}-viewer`;\n// Actions\nconst ACTION_SELECT = 'select';\nconst ACTION_MOVE = 'move';\nconst ACTION_SCALE = 'scale';\nconst ACTION_ROTATE = 'rotate';\nconst ACTION_TRANSFORM = 'transform';\nconst ACTION_NONE = 'none';\nconst ACTION_RESIZE_NORTH = 'n-resize';\nconst ACTION_RESIZE_EAST = 'e-resize';\nconst ACTION_RESIZE_SOUTH = 's-resize';\nconst ACTION_RESIZE_WEST = 'w-resize';\nconst ACTION_RESIZE_NORTHEAST = 'ne-resize';\nconst ACTION_RESIZE_NORTHWEST = 'nw-resize';\nconst ACTION_RESIZE_SOUTHEAST = 'se-resize';\nconst ACTION_RESIZE_SOUTHWEST = 'sw-resize';\n// Attributes\nconst ATTRIBUTE_ACTION = 'action';\n// Native events\nconst EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';\nconst EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';\nconst EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';\nconst EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;\nconst EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;\nconst EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;\nconst EVENT_ERROR = 'error';\nconst EVENT_KEYDOWN = 'keydown';\nconst EVENT_LOAD = 'load';\nconst EVENT_RESIZE = 'resize';\nconst EVENT_WHEEL = 'wheel';\n// Custom events\nconst EVENT_ACTION = 'action';\nconst EVENT_ACTION_END = 'actionend';\nconst EVENT_ACTION_MOVE = 'actionmove';\nconst EVENT_ACTION_START = 'actionstart';\nconst EVENT_CHANGE = 'change';\nconst EVENT_TRANSFORM = 'transform';\n\n/**\n * Check if the given value is a string.\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if the given value is a string, else `false`.\n */\nfunction isString(value) {\n    return typeof value === 'string';\n}\n/**\n * Check if the given value is not a number.\n */\nconst isNaN = Number.isNaN || WINDOW.isNaN;\n/**\n * Check if the given value is a number.\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if the given value is a number, else `false`.\n */\nfunction isNumber(value) {\n    return typeof value === 'number' && !isNaN(value);\n}\n/**\n * Check if the given value is a positive number.\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.\n */\nfunction isPositiveNumber(value) {\n    return isNumber(value) && value > 0 && value < Infinity;\n}\n/**\n * Check if the given value is undefined.\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if the given value is undefined, else `false`.\n */\nfunction isUndefined(value) {\n    return typeof value === 'undefined';\n}\n/**\n * Check if the given value is an object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is an object, else `false`.\n */\nfunction isObject(value) {\n    return typeof value === 'object' && value !== null;\n}\nconst { hasOwnProperty } = Object.prototype;\n/**\n * Check if the given value is a plain object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.\n */\nfunction isPlainObject(value) {\n    if (!isObject(value)) {\n        return false;\n    }\n    try {\n        const { constructor } = value;\n        const { prototype } = constructor;\n        return constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');\n    }\n    catch (error) {\n        return false;\n    }\n}\n/**\n * Check if the given value is a function.\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if the given value is a function, else `false`.\n */\nfunction isFunction(value) {\n    return typeof value === 'function';\n}\n/**\n * Check if the given node is an element.\n * @param {*} node The node to check.\n * @returns {boolean} Returns `true` if the given node is an element; otherwise, `false`.\n */\nfunction isElement(node) {\n    return typeof node === 'object' && node !== null && node.nodeType === 1;\n}\nconst REGEXP_CAMEL_CASE = /([a-z\\d])([A-Z])/g;\n/**\n * Transform the given string from camelCase to kebab-case.\n * @param {string} value The value to transform.\n * @returns {string} Returns the transformed value.\n */\nfunction toKebabCase(value) {\n    return String(value).replace(REGEXP_CAMEL_CASE, '$1-$2').toLowerCase();\n}\nconst REGEXP_KEBAB_CASE = /-[A-z\\d]/g;\n/**\n * Transform the given string from kebab-case to camelCase.\n * @param {string} value The value to transform.\n * @returns {string} Returns the transformed value.\n */\nfunction toCamelCase(value) {\n    return value.replace(REGEXP_KEBAB_CASE, (substring) => substring.slice(1).toUpperCase());\n}\nconst REGEXP_SPACES = /\\s\\s*/;\n/**\n * Remove event listener from the event target.\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener}\n * @param {EventTarget} target The target of the event.\n * @param {string} types The types of the event.\n * @param {EventListenerOrEventListenerObject} listener The listener of the event.\n * @param {EventListenerOptions} [options] The options specify characteristics about the event listener.\n */\nfunction off(target, types, listener, options) {\n    types.trim().split(REGEXP_SPACES).forEach((type) => {\n        target.removeEventListener(type, listener, options);\n    });\n}\n/**\n * Add event listener to the event target.\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener}\n * @param {EventTarget} target The target of the event.\n * @param {string} types The types of the event.\n * @param {EventListenerOrEventListenerObject} listener The listener of the event.\n * @param {AddEventListenerOptions} [options] The options specify characteristics about the event listener.\n */\nfunction on(target, types, listener, options) {\n    types.trim().split(REGEXP_SPACES).forEach((type) => {\n        target.addEventListener(type, listener, options);\n    });\n}\n/**\n * Add once event listener to the event target.\n * @param {EventTarget} target The target of the event.\n * @param {string} types The types of the event.\n * @param {EventListenerOrEventListenerObject} listener The listener of the event.\n * @param {AddEventListenerOptions} [options] The options specify characteristics about the event listener.\n */\nfunction once(target, types, listener, options) {\n    on(target, types, listener, Object.assign(Object.assign({}, options), { once: true }));\n}\nconst defaultEventOptions = {\n    bubbles: true,\n    cancelable: true,\n    composed: true,\n};\n/**\n * Dispatch event on the event target.\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent}\n * @param {EventTarget} target The target of the event.\n * @param {string} type The name of the event.\n * @param {*} [detail] The data passed when initializing the event.\n * @param {CustomEventInit} [options] The other event options.\n * @returns {boolean} Returns the result value.\n */\nfunction emit(target, type, detail, options) {\n    return target.dispatchEvent(new CustomEvent(type, Object.assign(Object.assign(Object.assign({}, defaultEventOptions), { detail }), options)));\n}\nconst resolvedPromise = Promise.resolve();\n/**\n * Defers the callback to be executed after the next DOM update cycle.\n * @param {*} [context] The `this` context.\n * @param {Function} [callback] The callback to execute after the next DOM update cycle.\n * @returns {Promise} A promise that resolves to nothing.\n */\nfunction nextTick(context, callback) {\n    return callback\n        ? resolvedPromise.then(context ? callback.bind(context) : callback)\n        : resolvedPromise;\n}\n/**\n * Get the offset base on the document.\n * @param {Element} element The target element.\n * @returns {object} The offset data.\n */\nfunction getOffset(element) {\n    const { documentElement } = element.ownerDocument;\n    const box = element.getBoundingClientRect();\n    return {\n        left: box.left + (WINDOW.pageXOffset - documentElement.clientLeft),\n        top: box.top + (WINDOW.pageYOffset - documentElement.clientTop),\n    };\n}\nconst REGEXP_ANGLE_UNIT = /deg|g?rad|turn$/i;\n/**\n * Convert an angle to a radian number.\n * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/angle}\n * @param {number|string} angle The angle to convert.\n * @returns {number} Returns the radian number.\n */\nfunction toAngleInRadian(angle) {\n    const value = parseFloat(angle) || 0;\n    if (value !== 0) {\n        const [unit = 'rad'] = String(angle).match(REGEXP_ANGLE_UNIT) || [];\n        switch (unit.toLowerCase()) {\n            case 'deg':\n                return (value / 360) * (Math.PI * 2);\n            case 'grad':\n                return (value / 400) * (Math.PI * 2);\n            case 'turn':\n                return value * (Math.PI * 2);\n        }\n    }\n    return value;\n}\nconst SIZE_ADJUSTMENT_TYPE_CONTAIN = 'contain';\nconst SIZE_ADJUSTMENT_TYPE_COVER = 'cover';\n/**\n * Get the max sizes in a rectangle under the given aspect ratio.\n * @param {object} data The original sizes.\n * @param {string} [type] The adjust type.\n * @returns {object} Returns the result sizes.\n */\nfunction getAdjustedSizes(data, type = SIZE_ADJUSTMENT_TYPE_CONTAIN) {\n    const { aspectRatio } = data;\n    let { width, height } = data;\n    const isValidWidth = isPositiveNumber(width);\n    const isValidHeight = isPositiveNumber(height);\n    if (isValidWidth && isValidHeight) {\n        const adjustedWidth = height * aspectRatio;\n        if ((type === SIZE_ADJUSTMENT_TYPE_CONTAIN && adjustedWidth > width)\n            || (type === SIZE_ADJUSTMENT_TYPE_COVER && adjustedWidth < width)) {\n            height = width / aspectRatio;\n        }\n        else {\n            width = height * aspectRatio;\n        }\n    }\n    else if (isValidWidth) {\n        height = width / aspectRatio;\n    }\n    else if (isValidHeight) {\n        width = height * aspectRatio;\n    }\n    return {\n        width,\n        height,\n    };\n}\n/**\n * Multiply multiple matrices.\n * @param {Array} matrix The first matrix.\n * @param {Array} args The rest matrices.\n * @returns {Array} Returns the result matrix.\n */\nfunction multiplyMatrices(matrix, ...args) {\n    if (args.length === 0) {\n        return matrix;\n    }\n    const [a1, b1, c1, d1, e1, f1] = matrix;\n    const [a2, b2, c2, d2, e2, f2] = args[0];\n    // ┌ a1 c1 e1 ┐   ┌ a2 c2 e2 ┐\n    // │ b1 d1 f1 │ × │ b2 d2 f2 │\n    // └ 0  0  1  ┘   └ 0  0  1  ┘\n    matrix = [\n        a1 * a2 + c1 * b2 /* + e1 * 0 */,\n        b1 * a2 + d1 * b2 /* + f1 * 0 */,\n        a1 * c2 + c1 * d2 /* + e1 * 0 */,\n        b1 * c2 + d1 * d2 /* + f1 * 0 */,\n        a1 * e2 + c1 * f2 + e1 /* * 1 */,\n        b1 * e2 + d1 * f2 + f1 /* * 1 */,\n    ];\n    return multiplyMatrices(matrix, ...args.slice(1));\n}\n\nexport { ACTION_MOVE, ACTION_NONE, ACTION_RESIZE_EAST, ACTION_RESIZE_NORTH, ACTION_RESIZE_NORTHEAST, ACTION_RESIZE_NORTHWEST, ACTION_RESIZE_SOUTH, ACTION_RESIZE_SOUTHEAST, ACTION_RESIZE_SOUTHWEST, ACTION_RESIZE_WEST, ACTION_ROTATE, ACTION_SCALE, ACTION_SELECT, ACTION_TRANSFORM, ATTRIBUTE_ACTION, CROPPER_CANVAS, CROPPER_CROSSHAIR, CROPPER_GIRD, CROPPER_HANDLE, CROPPER_IMAGE, CROPPER_SELECTION, CROPPER_SHADE, CROPPER_VIEWER, EVENT_ACTION, EVENT_ACTION_END, EVENT_ACTION_MOVE, EVENT_ACTION_START, EVENT_CHANGE, EVENT_ERROR, EVENT_KEYDOWN, EVENT_LOAD, EVENT_POINTER_DOWN, EVENT_POINTER_MOVE, EVENT_POINTER_UP, EVENT_RESIZE, EVENT_TOUCH_END, EVENT_TOUCH_MOVE, EVENT_TOUCH_START, EVENT_TRANSFORM, EVENT_WHEEL, HAS_POINTER_EVENT, IS_BROWSER, IS_TOUCH_DEVICE, NAMESPACE, WINDOW, emit, getAdjustedSizes, getOffset, isElement, isFunction, isNaN, isNumber, isObject, isPlainObject, isPositiveNumber, isString, isUndefined, multiplyMatrices, nextTick, off, on, once, toAngleInRadian, toCamelCase, toKebabCase };\n","import { WINDOW, toCamelCase, toKebabCase, isNaN, isUndefined, isNumber, emit, nextTick, isObject, IS_BROWSER } from '@cropper/utils';\n\nvar style = `:host([hidden]){display:none!important}`;\n\nconst REGEXP_SUFFIX = /left|top|width|height/i;\nconst DEFAULT_SHADOW_ROOT_MODE = 'open';\nconst shadowRoots = new WeakMap();\nconst styleSheets = new WeakMap();\nconst tagNames = new Map();\nconst supportsAdoptedStyleSheets = WINDOW.document && Array.isArray(WINDOW.document.adoptedStyleSheets) && 'replaceSync' in WINDOW.CSSStyleSheet.prototype;\nclass CropperElement extends HTMLElement {\n    get $sharedStyle() {\n        return `${this.themeColor ? `:host{--theme-color: ${this.themeColor};}` : ''}${style}`;\n    }\n    constructor() {\n        var _a, _b;\n        super();\n        this.shadowRootMode = DEFAULT_SHADOW_ROOT_MODE;\n        this.slottable = true;\n        const name = (_b = (_a = Object.getPrototypeOf(this)) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.$name;\n        if (name) {\n            tagNames.set(name, this.tagName.toLowerCase());\n        }\n    }\n    static get observedAttributes() {\n        return [\n            'shadow-root-mode',\n            'slottable',\n            'theme-color',\n        ];\n    }\n    // Convert attribute to property\n    attributeChangedCallback(name, oldValue, newValue) {\n        if (Object.is(newValue, oldValue)) {\n            return;\n        }\n        const propertyName = toCamelCase(name);\n        const oldPropertyValue = this[propertyName];\n        let newPropertyValue = newValue;\n        switch (typeof oldPropertyValue) {\n            case 'boolean':\n                newPropertyValue = newValue !== null && newValue !== 'false';\n                break;\n            case 'number':\n                newPropertyValue = Number(newValue);\n                break;\n        }\n        this[propertyName] = newPropertyValue;\n        switch (name) {\n            case 'theme-color': {\n                const styleSheet = styleSheets.get(this);\n                const styles = this.$sharedStyle;\n                if (styleSheet && styles) {\n                    if (supportsAdoptedStyleSheets) {\n                        styleSheet.replaceSync(styles);\n                    }\n                    else {\n                        styleSheet.textContent = styles;\n                    }\n                }\n                break;\n            }\n        }\n    }\n    // Convert property to attribute\n    $propertyChangedCallback(name, oldValue, newValue) {\n        if (Object.is(newValue, oldValue)) {\n            return;\n        }\n        name = toKebabCase(name);\n        switch (typeof newValue) {\n            case 'boolean':\n                if (newValue === true) {\n                    if (!this.hasAttribute(name)) {\n                        this.setAttribute(name, '');\n                    }\n                }\n                else {\n                    this.removeAttribute(name);\n                }\n                break;\n            case 'number':\n                if (isNaN(newValue)) {\n                    newValue = '';\n                }\n                else {\n                    newValue = String(newValue);\n                }\n            // Fall through\n            // case 'string':\n            // eslint-disable-next-line no-fallthrough\n            default:\n                if (newValue) {\n                    if (this.getAttribute(name) !== newValue) {\n                        this.setAttribute(name, newValue);\n                    }\n                }\n                else {\n                    this.removeAttribute(name);\n                }\n        }\n    }\n    connectedCallback() {\n        // Observe properties after observed attributes\n        Object.getPrototypeOf(this).constructor.observedAttributes.forEach((attribute) => {\n            const property = toCamelCase(attribute);\n            let value = this[property];\n            if (!isUndefined(value)) {\n                this.$propertyChangedCallback(property, undefined, value);\n            }\n            Object.defineProperty(this, property, {\n                enumerable: true,\n                configurable: true,\n                get() {\n                    return value;\n                },\n                set(newValue) {\n                    const oldValue = value;\n                    value = newValue;\n                    this.$propertyChangedCallback(property, oldValue, newValue);\n                },\n            });\n        });\n        const shadow = this.attachShadow({\n            mode: this.shadowRootMode || DEFAULT_SHADOW_ROOT_MODE,\n        });\n        if (!this.shadowRoot) {\n            shadowRoots.set(this, shadow);\n        }\n        styleSheets.set(this, this.$addStyles(this.$sharedStyle));\n        if (this.$style) {\n            this.$addStyles(this.$style);\n        }\n        if (this.$template) {\n            const template = document.createElement('template');\n            template.innerHTML = this.$template;\n            shadow.appendChild(template.content);\n        }\n        if (this.slottable) {\n            const slot = document.createElement('slot');\n            shadow.appendChild(slot);\n        }\n    }\n    disconnectedCallback() {\n        if (styleSheets.has(this)) {\n            styleSheets.delete(this);\n        }\n        if (shadowRoots.has(this)) {\n            shadowRoots.delete(this);\n        }\n    }\n    // eslint-disable-next-line class-methods-use-this\n    $getTagNameOf(name) {\n        var _a;\n        return (_a = tagNames.get(name)) !== null && _a !== void 0 ? _a : name;\n    }\n    $setStyles(properties) {\n        Object.keys(properties).forEach((property) => {\n            let value = properties[property];\n            if (isNumber(value)) {\n                if (value !== 0 && REGEXP_SUFFIX.test(property)) {\n                    value = `${value}px`;\n                }\n                else {\n                    value = String(value);\n                }\n            }\n            this.style[property] = value;\n        });\n        return this;\n    }\n    /**\n     * Outputs the shadow root of the element.\n     * @returns {ShadowRoot} Returns the shadow root.\n     */\n    $getShadowRoot() {\n        return this.shadowRoot || shadowRoots.get(this);\n    }\n    /**\n     * Adds styles to the shadow root.\n     * @param {string} styles The styles to add.\n     * @returns {CSSStyleSheet|HTMLStyleElement} Returns the generated style sheet.\n     */\n    $addStyles(styles) {\n        let styleSheet;\n        const shadow = this.$getShadowRoot();\n        if (supportsAdoptedStyleSheets) {\n            styleSheet = new CSSStyleSheet();\n            styleSheet.replaceSync(styles);\n            shadow.adoptedStyleSheets = shadow.adoptedStyleSheets.concat(styleSheet);\n        }\n        else {\n            styleSheet = document.createElement('style');\n            styleSheet.textContent = styles;\n            shadow.appendChild(styleSheet);\n        }\n        return styleSheet;\n    }\n    /**\n     * Dispatches an event at the element.\n     * @param {string} type The name of the event.\n     * @param {*} [detail] The data passed when initializing the event.\n     * @param {CustomEventInit} [options] The other event options.\n     * @returns {boolean} Returns the result value.\n     */\n    $emit(type, detail, options) {\n        return emit(this, type, detail, options);\n    }\n    /**\n     * Defers the callback to be executed after the next DOM update cycle.\n     * @param {Function} [callback] The callback to execute after the next DOM update cycle.\n     * @returns {Promise} A promise that resolves to nothing.\n     */\n    $nextTick(callback) {\n        return nextTick(this, callback);\n    }\n    /**\n     * Defines the constructor as a new custom element.\n     * {@link https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define}\n     * @param {string|object} [name] The element name.\n     * @param {object} [options] The element definition options.\n     */\n    static $define(name, options) {\n        if (isObject(name)) {\n            options = name;\n            name = '';\n        }\n        if (!name) {\n            name = this.$name || this.name;\n        }\n        name = toKebabCase(name);\n        if (IS_BROWSER && WINDOW.customElements && !WINDOW.customElements.get(name)) {\n            customElements.define(name, this, options);\n        }\n    }\n}\nCropperElement.$version = '2.0.0';\n\nexport { CropperElement as default };\n","import CropperElement from '@cropper/element';\nimport { CROPPER_CANVAS, ACTION_NONE, on, EVENT_POINTER_DOWN, EVENT_POINTER_MOVE, EVENT_POINTER_UP, EVENT_WHEEL, off, isNumber, isElement, ATTRIBUTE_ACTION, EVENT_ACTION_START, EVENT_ACTION_MOVE, ACTION_TRANSFORM, EVENT_ACTION, EVENT_ACTION_END, ACTION_SCALE, isString, isPlainObject, isPositiveNumber, getAdjustedSizes, CROPPER_IMAGE, isFunction, ACTION_ROTATE } from '@cropper/utils';\n\nvar style = `:host{display:block;min-height:100px;min-width:200px;overflow:hidden;position:relative;touch-action:none;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}:host([background]){background-color:#fff;background-image:repeating-linear-gradient(45deg,#ccc 25%,transparent 0,transparent 75%,#ccc 0,#ccc),repeating-linear-gradient(45deg,#ccc 25%,transparent 0,transparent 75%,#ccc 0,#ccc);background-image:repeating-conic-gradient(#ccc 0 25%,#fff 0 50%);background-position:0 0,.5rem .5rem;background-size:1rem 1rem}:host([disabled]){pointer-events:none}:host([disabled]):after{bottom:0;content:\"\";cursor:not-allowed;display:block;left:0;pointer-events:none;position:absolute;right:0;top:0}`;\n\nclass CropperCanvas extends CropperElement {\n    constructor() {\n        super(...arguments);\n        this.$onPointerDown = null;\n        this.$onPointerMove = null;\n        this.$onPointerUp = null;\n        this.$onWheel = null;\n        this.$wheeling = false;\n        this.$pointers = new Map();\n        this.$style = style;\n        this.$action = ACTION_NONE;\n        this.background = false;\n        this.disabled = false;\n        this.scaleStep = 0.1;\n        this.themeColor = '#39f';\n    }\n    static get observedAttributes() {\n        return super.observedAttributes.concat([\n            'background',\n            'disabled',\n            'scale-step',\n        ]);\n    }\n    connectedCallback() {\n        super.connectedCallback();\n        if (!this.disabled) {\n            this.$bind();\n        }\n    }\n    disconnectedCallback() {\n        if (!this.disabled) {\n            this.$unbind();\n        }\n        super.disconnectedCallback();\n    }\n    $propertyChangedCallback(name, oldValue, newValue) {\n        if (Object.is(newValue, oldValue)) {\n            return;\n        }\n        super.$propertyChangedCallback(name, oldValue, newValue);\n        switch (name) {\n            case 'disabled':\n                if (newValue) {\n                    this.$unbind();\n                }\n                else {\n                    this.$bind();\n                }\n                break;\n        }\n    }\n    $bind() {\n        if (!this.$onPointerDown) {\n            this.$onPointerDown = this.$handlePointerDown.bind(this);\n            on(this, EVENT_POINTER_DOWN, this.$onPointerDown);\n        }\n        if (!this.$onPointerMove) {\n            this.$onPointerMove = this.$handlePointerMove.bind(this);\n            on(this.ownerDocument, EVENT_POINTER_MOVE, this.$onPointerMove);\n        }\n        if (!this.$onPointerUp) {\n            this.$onPointerUp = this.$handlePointerUp.bind(this);\n            on(this.ownerDocument, EVENT_POINTER_UP, this.$onPointerUp);\n        }\n        if (!this.$onWheel) {\n            this.$onWheel = this.$handleWheel.bind(this);\n            on(this, EVENT_WHEEL, this.$onWheel, {\n                passive: false,\n                capture: true,\n            });\n        }\n    }\n    $unbind() {\n        if (this.$onPointerDown) {\n            off(this, EVENT_POINTER_DOWN, this.$onPointerDown);\n            this.$onPointerDown = null;\n        }\n        if (this.$onPointerMove) {\n            off(this.ownerDocument, EVENT_POINTER_MOVE, this.$onPointerMove);\n            this.$onPointerMove = null;\n        }\n        if (this.$onPointerUp) {\n            off(this.ownerDocument, EVENT_POINTER_UP, this.$onPointerUp);\n            this.$onPointerUp = null;\n        }\n        if (this.$onWheel) {\n            off(this, EVENT_WHEEL, this.$onWheel, {\n                capture: true,\n            });\n            this.$onWheel = null;\n        }\n    }\n    $handlePointerDown(event) {\n        const { buttons, button, type } = event;\n        if (this.disabled || (\n        // Handle pointer or mouse event, and ignore touch event\n        ((type === 'pointerdown' && event.pointerType === 'mouse') || type === 'mousedown') && (\n        // No primary button (Usually the left button)\n        (isNumber(buttons) && buttons !== 1) || (isNumber(button) && button !== 0)\n            // Open context menu\n            || event.ctrlKey))) {\n            return;\n        }\n        const { $pointers } = this;\n        let action = '';\n        if (event.changedTouches) {\n            Array.from(event.changedTouches).forEach(({ identifier, pageX, pageY, }) => {\n                $pointers.set(identifier, {\n                    startX: pageX,\n                    startY: pageY,\n                    endX: pageX,\n                    endY: pageY,\n                });\n            });\n        }\n        else {\n            const { pointerId = 0, pageX, pageY } = event;\n            $pointers.set(pointerId, {\n                startX: pageX,\n                startY: pageY,\n                endX: pageX,\n                endY: pageY,\n            });\n        }\n        if ($pointers.size > 1) {\n            action = ACTION_TRANSFORM;\n        }\n        else if (isElement(event.target)) {\n            action = event.target.action || event.target.getAttribute(ATTRIBUTE_ACTION) || '';\n        }\n        if (this.$emit(EVENT_ACTION_START, {\n            action,\n            relatedEvent: event,\n        }) === false) {\n            return;\n        }\n        // Prevent page zooming in the browsers for iOS.\n        event.preventDefault();\n        this.$action = action;\n        this.style.willChange = 'transform';\n    }\n    $handlePointerMove(event) {\n        const { $action, $pointers } = this;\n        if (this.disabled || $action === ACTION_NONE || $pointers.size === 0) {\n            return;\n        }\n        if (this.$emit(EVENT_ACTION_MOVE, {\n            action: $action,\n            relatedEvent: event,\n        }) === false) {\n            return;\n        }\n        // Prevent page scrolling.\n        event.preventDefault();\n        if (event.changedTouches) {\n            Array.from(event.changedTouches).forEach(({ identifier, pageX, pageY, }) => {\n                const pointer = $pointers.get(identifier);\n                if (pointer) {\n                    Object.assign(pointer, {\n                        endX: pageX,\n                        endY: pageY,\n                    });\n                }\n            });\n        }\n        else {\n            const { pointerId = 0, pageX, pageY } = event;\n            const pointer = $pointers.get(pointerId);\n            if (pointer) {\n                Object.assign(pointer, {\n                    endX: pageX,\n                    endY: pageY,\n                });\n            }\n        }\n        const detail = {\n            action: $action,\n            relatedEvent: event,\n        };\n        if ($action === ACTION_TRANSFORM) {\n            const pointers2 = new Map($pointers);\n            let maxRotateRate = 0;\n            let maxScaleRate = 0;\n            let rotate = 0;\n            let scale = 0;\n            let centerX = event.pageX;\n            let centerY = event.pageY;\n            $pointers.forEach((pointer, pointerId) => {\n                pointers2.delete(pointerId);\n                pointers2.forEach((pointer2) => {\n                    let x1 = pointer2.startX - pointer.startX;\n                    let y1 = pointer2.startY - pointer.startY;\n                    let x2 = pointer2.endX - pointer.endX;\n                    let y2 = pointer2.endY - pointer.endY;\n                    let z1 = 0;\n                    let z2 = 0;\n                    let a1 = 0;\n                    let a2 = 0;\n                    if (x1 === 0) {\n                        if (y1 < 0) {\n                            a1 = Math.PI * 2;\n                        }\n                        else if (y1 > 0) {\n                            a1 = Math.PI;\n                        }\n                    }\n                    else if (x1 > 0) {\n                        a1 = (Math.PI / 2) + Math.atan(y1 / x1);\n                    }\n                    else if (x1 < 0) {\n                        a1 = (Math.PI * 1.5) + Math.atan(y1 / x1);\n                    }\n                    if (x2 === 0) {\n                        if (y2 < 0) {\n                            a2 = Math.PI * 2;\n                        }\n                        else if (y2 > 0) {\n                            a2 = Math.PI;\n                        }\n                    }\n                    else if (x2 > 0) {\n                        a2 = (Math.PI / 2) + Math.atan(y2 / x2);\n                    }\n                    else if (x2 < 0) {\n                        a2 = (Math.PI * 1.5) + Math.atan(y2 / x2);\n                    }\n                    if (a2 > 0 || a1 > 0) {\n                        const rotateRate = a2 - a1;\n                        const absRotateRate = Math.abs(rotateRate);\n                        if (absRotateRate > maxRotateRate) {\n                            maxRotateRate = absRotateRate;\n                            rotate = rotateRate;\n                            centerX = (pointer.startX + pointer2.startX) / 2;\n                            centerY = (pointer.startY + pointer2.startY) / 2;\n                        }\n                    }\n                    x1 = Math.abs(x1);\n                    y1 = Math.abs(y1);\n                    x2 = Math.abs(x2);\n                    y2 = Math.abs(y2);\n                    if (x1 > 0 && y1 > 0) {\n                        z1 = Math.sqrt((x1 * x1) + (y1 * y1));\n                    }\n                    else if (x1 > 0) {\n                        z1 = x1;\n                    }\n                    else if (y1 > 0) {\n                        z1 = y1;\n                    }\n                    if (x2 > 0 && y2 > 0) {\n                        z2 = Math.sqrt((x2 * x2) + (y2 * y2));\n                    }\n                    else if (x2 > 0) {\n                        z2 = x2;\n                    }\n                    else if (y2 > 0) {\n                        z2 = y2;\n                    }\n                    if (z1 > 0 && z2 > 0) {\n                        const scaleRate = (z2 - z1) / z1;\n                        const absScaleRate = Math.abs(scaleRate);\n                        if (absScaleRate > maxScaleRate) {\n                            maxScaleRate = absScaleRate;\n                            scale = scaleRate;\n                            centerX = (pointer.startX + pointer2.startX) / 2;\n                            centerY = (pointer.startY + pointer2.startY) / 2;\n                        }\n                    }\n                });\n            });\n            const rotatable = maxRotateRate > 0;\n            const scalable = maxScaleRate > 0;\n            if (rotatable && scalable) {\n                detail.rotate = rotate;\n                detail.scale = scale;\n                detail.centerX = centerX;\n                detail.centerY = centerY;\n            }\n            else if (rotatable) {\n                detail.action = ACTION_ROTATE;\n                detail.rotate = rotate;\n                detail.centerX = centerX;\n                detail.centerY = centerY;\n            }\n            else if (scalable) {\n                detail.action = ACTION_SCALE;\n                detail.scale = scale;\n                detail.centerX = centerX;\n                detail.centerY = centerY;\n            }\n            else {\n                detail.action = ACTION_NONE;\n            }\n        }\n        else {\n            const [pointer] = Array.from($pointers.values());\n            Object.assign(detail, pointer);\n        }\n        // Override the starting coordinate\n        $pointers.forEach((pointer) => {\n            pointer.startX = pointer.endX;\n            pointer.startY = pointer.endY;\n        });\n        if (detail.action !== ACTION_NONE) {\n            this.$emit(EVENT_ACTION, detail, {\n                cancelable: false,\n            });\n        }\n    }\n    $handlePointerUp(event) {\n        const { $action, $pointers } = this;\n        if (this.disabled || $action === ACTION_NONE) {\n            return;\n        }\n        if (this.$emit(EVENT_ACTION_END, {\n            action: $action,\n            relatedEvent: event,\n        }) === false) {\n            return;\n        }\n        event.preventDefault();\n        if (event.changedTouches) {\n            Array.from(event.changedTouches).forEach(({ identifier, }) => {\n                $pointers.delete(identifier);\n            });\n        }\n        else {\n            const { pointerId = 0 } = event;\n            $pointers.delete(pointerId);\n        }\n        if ($pointers.size === 0) {\n            this.style.willChange = '';\n            this.$action = ACTION_NONE;\n        }\n    }\n    $handleWheel(event) {\n        if (this.disabled) {\n            return;\n        }\n        event.preventDefault();\n        // Limit wheel speed to prevent zoom too fast (#21)\n        if (this.$wheeling) {\n            return;\n        }\n        this.$wheeling = true;\n        // Debounce by 50ms\n        setTimeout(() => {\n            this.$wheeling = false;\n        }, 50);\n        const delta = event.deltaY > 0 ? -1 : 1;\n        const scale = delta * this.scaleStep;\n        this.$emit(EVENT_ACTION, {\n            action: ACTION_SCALE,\n            scale,\n            relatedEvent: event,\n        }, {\n            cancelable: false,\n        });\n    }\n    /**\n     * Changes the current action to a new one.\n     * @param {string} action The new action.\n     * @returns {CropperCanvas} Returns `this` for chaining.\n     */\n    $setAction(action) {\n        if (isString(action)) {\n            this.$action = action;\n        }\n        return this;\n    }\n    /**\n     * Generates a real canvas element, with the image draw into if there is one.\n     * @param {object} [options] The available options.\n     * @param {number} [options.width] The width of the canvas.\n     * @param {number} [options.height] The height of the canvas.\n     * @param {Function} [options.beforeDraw] The function called before drawing the image onto the canvas.\n     * @returns {Promise} Returns a promise that resolves to the generated canvas element.\n     */\n    $toCanvas(options) {\n        return new Promise((resolve, reject) => {\n            if (!this.isConnected) {\n                reject(new Error('The current element is not connected to the DOM.'));\n                return;\n            }\n            const canvas = document.createElement('canvas');\n            let width = this.offsetWidth;\n            let height = this.offsetHeight;\n            let scale = 1;\n            if (isPlainObject(options)\n                && (isPositiveNumber(options.width) || isPositiveNumber(options.height))) {\n                ({ width, height } = getAdjustedSizes({\n                    aspectRatio: width / height,\n                    width: options.width,\n                    height: options.height,\n                }));\n                scale = width / this.offsetWidth;\n            }\n            canvas.width = width;\n            canvas.height = height;\n            const cropperImage = this.querySelector(this.$getTagNameOf(CROPPER_IMAGE));\n            if (!cropperImage) {\n                resolve(canvas);\n                return;\n            }\n            cropperImage.$ready().then((image) => {\n                const context = canvas.getContext('2d');\n                if (context) {\n                    const [a, b, c, d, e, f] = cropperImage.$getTransform();\n                    let newE = e;\n                    let newF = f;\n                    let destWidth = image.naturalWidth;\n                    let destHeight = image.naturalHeight;\n                    if (scale !== 1) {\n                        newE *= scale;\n                        newF *= scale;\n                        destWidth *= scale;\n                        destHeight *= scale;\n                    }\n                    const centerX = destWidth / 2;\n                    const centerY = destHeight / 2;\n                    context.fillStyle = 'transparent';\n                    context.fillRect(0, 0, width, height);\n                    if (isPlainObject(options) && isFunction(options.beforeDraw)) {\n                        options.beforeDraw.call(this, context, canvas);\n                    }\n                    context.save();\n                    // Move the transform origin to the center of the image.\n                    // https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin\n                    context.translate(centerX, centerY);\n                    context.transform(a, b, c, d, newE, newF);\n                    // Reset the transform origin to the top-left of the image.\n                    context.translate(-centerX, -centerY);\n                    context.drawImage(image, 0, 0, destWidth, destHeight);\n                    context.restore();\n                }\n                resolve(canvas);\n            }).catch(reject);\n        });\n    }\n}\nCropperCanvas.$name = CROPPER_CANVAS;\nCropperCanvas.$version = '2.0.0';\n\nexport { CropperCanvas as default };\n","import CropperElement from '@cropper/element';\nimport { CROPPER_IMAGE, CROPPER_CANVAS, on, EVENT_ACTION_START, EVENT_ACTION_END, EVENT_ACTION, EVENT_LOAD, off, ACTION_TRANSFORM, ACTION_ROTATE, ACTION_SCALE, ACTION_NONE, CROPPER_SELECTION, ACTION_MOVE, once, EVENT_ERROR, isFunction, isNumber, toAngleInRadian, multiplyMatrices, EVENT_TRANSFORM } from '@cropper/utils';\n\nvar style = `:host{display:inline-block}img{display:block;height:100%;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}`;\n\nconst canvasCache = new WeakMap();\nconst NATIVE_ATTRIBUTES = [\n    'alt',\n    'crossorigin',\n    'decoding',\n    'importance',\n    'loading',\n    'referrerpolicy',\n    'sizes',\n    'src',\n    'srcset',\n];\nclass CropperImage extends CropperElement {\n    constructor() {\n        super(...arguments);\n        this.$matrix = [1, 0, 0, 1, 0, 0];\n        this.$onLoad = null;\n        this.$onCanvasAction = null;\n        this.$onCanvasActionEnd = null;\n        this.$onCanvasActionStart = null;\n        this.$actionStartTarget = null;\n        this.$style = style;\n        this.$image = new Image();\n        this.initialCenterSize = 'contain';\n        this.rotatable = false;\n        this.scalable = false;\n        this.skewable = false;\n        this.slottable = false;\n        this.translatable = false;\n    }\n    set $canvas(element) {\n        canvasCache.set(this, element);\n    }\n    get $canvas() {\n        return canvasCache.get(this);\n    }\n    static get observedAttributes() {\n        return super.observedAttributes.concat(NATIVE_ATTRIBUTES, [\n            'initial-center-size',\n            'rotatable',\n            'scalable',\n            'skewable',\n            'translatable',\n        ]);\n    }\n    attributeChangedCallback(name, oldValue, newValue) {\n        if (Object.is(newValue, oldValue)) {\n            return;\n        }\n        super.attributeChangedCallback(name, oldValue, newValue);\n        // Inherits the native attributes\n        if (NATIVE_ATTRIBUTES.includes(name)) {\n            this.$image.setAttribute(name, newValue);\n        }\n    }\n    $propertyChangedCallback(name, oldValue, newValue) {\n        if (Object.is(newValue, oldValue)) {\n            return;\n        }\n        super.$propertyChangedCallback(name, oldValue, newValue);\n        switch (name) {\n            case 'initialCenterSize':\n                this.$nextTick(() => {\n                    this.$center(newValue);\n                });\n                break;\n        }\n    }\n    connectedCallback() {\n        super.connectedCallback();\n        const { $image } = this;\n        const $canvas = this.closest(this.$getTagNameOf(CROPPER_CANVAS));\n        if ($canvas) {\n            this.$canvas = $canvas;\n            this.$setStyles({\n                // Make it a block element to avoid side effects (#1074).\n                display: 'block',\n                position: 'absolute',\n            });\n            this.$onCanvasActionStart = (event) => {\n                var _a, _b;\n                this.$actionStartTarget = (_b = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.relatedEvent) === null || _b === void 0 ? void 0 : _b.target;\n            };\n            this.$onCanvasActionEnd = () => {\n                this.$actionStartTarget = null;\n            };\n            this.$onCanvasAction = this.$handleAction.bind(this);\n            on($canvas, EVENT_ACTION_START, this.$onCanvasActionStart);\n            on($canvas, EVENT_ACTION_END, this.$onCanvasActionEnd);\n            on($canvas, EVENT_ACTION, this.$onCanvasAction);\n        }\n        this.$onLoad = this.$handleLoad.bind(this);\n        on($image, EVENT_LOAD, this.$onLoad);\n        this.$getShadowRoot().appendChild($image);\n    }\n    disconnectedCallback() {\n        const { $image, $canvas } = this;\n        if ($canvas) {\n            if (this.$onCanvasActionStart) {\n                off($canvas, EVENT_ACTION_START, this.$onCanvasActionStart);\n                this.$onCanvasActionStart = null;\n            }\n            if (this.$onCanvasActionEnd) {\n                off($canvas, EVENT_ACTION_END, this.$onCanvasActionEnd);\n                this.$onCanvasActionEnd = null;\n            }\n            if (this.$onCanvasAction) {\n                off($canvas, EVENT_ACTION, this.$onCanvasAction);\n                this.$onCanvasAction = null;\n            }\n        }\n        if ($image && this.$onLoad) {\n            off($image, EVENT_LOAD, this.$onLoad);\n            this.$onLoad = null;\n        }\n        this.$getShadowRoot().removeChild($image);\n        super.disconnectedCallback();\n    }\n    $handleLoad() {\n        const { $image } = this;\n        this.$setStyles({\n            width: $image.naturalWidth,\n            height: $image.naturalHeight,\n        });\n        if (this.$canvas) {\n            this.$center(this.initialCenterSize);\n        }\n    }\n    $handleAction(event) {\n        if (this.hidden || !(this.rotatable || this.scalable || this.translatable)) {\n            return;\n        }\n        const { $canvas } = this;\n        const { detail } = event;\n        if (detail) {\n            const { relatedEvent } = detail;\n            let { action } = detail;\n            if (action === ACTION_TRANSFORM && (!this.rotatable || !this.scalable)) {\n                if (this.rotatable) {\n                    action = ACTION_ROTATE;\n                }\n                else if (this.scalable) {\n                    action = ACTION_SCALE;\n                }\n                else {\n                    action = ACTION_NONE;\n                }\n            }\n            switch (action) {\n                case ACTION_MOVE:\n                    if (this.translatable) {\n                        let $selection = null;\n                        if (relatedEvent) {\n                            $selection = relatedEvent.target.closest(this.$getTagNameOf(CROPPER_SELECTION));\n                        }\n                        if (!$selection) {\n                            $selection = $canvas.querySelector(this.$getTagNameOf(CROPPER_SELECTION));\n                        }\n                        if ($selection && $selection.multiple && !$selection.active) {\n                            $selection = $canvas.querySelector(`${this.$getTagNameOf(CROPPER_SELECTION)}[active]`);\n                        }\n                        if (!$selection || $selection.hidden || !$selection.movable || $selection.dynamic\n                            || !(this.$actionStartTarget && $selection.contains(this.$actionStartTarget))) {\n                            this.$move(detail.endX - detail.startX, detail.endY - detail.startY);\n                        }\n                    }\n                    break;\n                case ACTION_ROTATE:\n                    if (this.rotatable) {\n                        if (relatedEvent) {\n                            const { x, y } = this.getBoundingClientRect();\n                            this.$rotate(detail.rotate, relatedEvent.clientX - x, relatedEvent.clientY - y);\n                        }\n                        else {\n                            this.$rotate(detail.rotate);\n                        }\n                    }\n                    break;\n                case ACTION_SCALE:\n                    if (this.scalable) {\n                        if (relatedEvent) {\n                            const $selection = relatedEvent.target.closest(this.$getTagNameOf(CROPPER_SELECTION));\n                            if (!$selection\n                                || !$selection.zoomable\n                                || ($selection.zoomable && $selection.dynamic)) {\n                                const { x, y } = this.getBoundingClientRect();\n                                this.$zoom(detail.scale, relatedEvent.clientX - x, relatedEvent.clientY - y);\n                            }\n                        }\n                        else {\n                            this.$zoom(detail.scale);\n                        }\n                    }\n                    break;\n                case ACTION_TRANSFORM:\n                    if (this.rotatable && this.scalable) {\n                        const { rotate } = detail;\n                        let { scale } = detail;\n                        if (scale < 0) {\n                            scale = 1 / (1 - scale);\n                        }\n                        else {\n                            scale += 1;\n                        }\n                        const cos = Math.cos(rotate);\n                        const sin = Math.sin(rotate);\n                        const [scaleX, skewY, skewX, scaleY] = [\n                            cos * scale,\n                            sin * scale,\n                            -sin * scale,\n                            cos * scale,\n                        ];\n                        if (relatedEvent) {\n                            const clientRect = this.getBoundingClientRect();\n                            const x = relatedEvent.clientX - clientRect.x;\n                            const y = relatedEvent.clientY - clientRect.y;\n                            const [a, b, c, d] = this.$matrix;\n                            const originX = clientRect.width / 2;\n                            const originY = clientRect.height / 2;\n                            const moveX = x - originX;\n                            const moveY = y - originY;\n                            const translateX = ((moveX * d) - (c * moveY)) / ((a * d) - (c * b));\n                            const translateY = ((moveY * a) - (b * moveX)) / ((a * d) - (c * b));\n                            /**\n                             * Equals to\n                             * this.$rotate(rotate, x, y);\n                             * this.$scale(scale, x, y);\n                             */\n                            this.$transform(scaleX, skewY, skewX, scaleY, translateX * (1 - scaleX) + translateY * skewX, translateY * (1 - scaleY) + translateX * skewY);\n                        }\n                        else {\n                            /**\n                             * Equals to\n                             * this.$rotate(rotate);\n                             * this.$scale(scale);\n                             */\n                            this.$transform(scaleX, skewY, skewX, scaleY, 0, 0);\n                        }\n                    }\n                    break;\n            }\n        }\n    }\n    /**\n     * Defers the callback to execute after successfully loading the image.\n     * @param {Function} [callback] The callback to execute after successfully loading the image.\n     * @returns {Promise} Returns a promise that resolves to the image element.\n     */\n    $ready(callback) {\n        const { $image } = this;\n        const promise = new Promise((resolve, reject) => {\n            const error = new Error('Failed to load the image source');\n            if ($image.complete) {\n                if ($image.naturalWidth > 0 && $image.naturalHeight > 0) {\n                    resolve($image);\n                }\n                else {\n                    reject(error);\n                }\n            }\n            else {\n                const onLoad = () => {\n                    // eslint-disable-next-line @typescript-eslint/no-use-before-define\n                    off($image, EVENT_ERROR, onError);\n                    resolve($image);\n                };\n                const onError = () => {\n                    off($image, EVENT_LOAD, onLoad);\n                    reject(error);\n                };\n                once($image, EVENT_LOAD, onLoad);\n                once($image, EVENT_ERROR, onError);\n            }\n        });\n        if (isFunction(callback)) {\n            promise.then((image) => {\n                callback(image);\n                return image;\n            });\n        }\n        return promise;\n    }\n    /**\n     * Aligns the image to the center of its parent element.\n     * @param {string} [size] The size of the image.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $center(size) {\n        const { parentElement } = this;\n        if (!parentElement) {\n            return this;\n        }\n        const container = parentElement.getBoundingClientRect();\n        const containerWidth = container.width;\n        const containerHeight = container.height;\n        const { x, y, width, height, } = this.getBoundingClientRect();\n        const startX = x + (width / 2);\n        const startY = y + (height / 2);\n        const endX = container.x + (containerWidth / 2);\n        const endY = container.y + (containerHeight / 2);\n        this.$move(endX - startX, endY - startY);\n        if (size && (width !== containerWidth || height !== containerHeight)) {\n            const scaleX = containerWidth / width;\n            const scaleY = containerHeight / height;\n            switch (size) {\n                case 'cover':\n                    this.$scale(Math.max(scaleX, scaleY));\n                    break;\n                case 'contain':\n                    this.$scale(Math.min(scaleX, scaleY));\n                    break;\n            }\n        }\n        return this;\n    }\n    /**\n     * Moves the image.\n     * @param {number} x The moving distance in the horizontal direction.\n     * @param {number} [y] The moving distance in the vertical direction.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $move(x, y = x) {\n        if (this.translatable && isNumber(x) && isNumber(y)) {\n            const [a, b, c, d] = this.$matrix;\n            const e = ((x * d) - (c * y)) / ((a * d) - (c * b));\n            const f = ((y * a) - (b * x)) / ((a * d) - (c * b));\n            this.$translate(e, f);\n        }\n        return this;\n    }\n    /**\n     * Moves the image to a specific position.\n     * @param {number} x The new position in the horizontal direction.\n     * @param {number} [y] The new position in the vertical direction.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $moveTo(x, y = x) {\n        if (this.translatable && isNumber(x) && isNumber(y)) {\n            const [a, b, c, d] = this.$matrix;\n            const e = ((x * d) - (c * y)) / ((a * d) - (c * b));\n            const f = ((y * a) - (b * x)) / ((a * d) - (c * b));\n            this.$setTransform(a, b, c, d, e, f);\n        }\n        return this;\n    }\n    /**\n     * Rotates the image.\n     * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate}\n     * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/rotate}\n     * @param {number|string} angle The rotation angle (in radians).\n     * @param {number} [x] The rotation origin in the horizontal, defaults to the center of the image.\n     * @param {number} [y] The rotation origin in the vertical, defaults to the center of the image.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $rotate(angle, x, y) {\n        if (this.rotatable) {\n            const radian = toAngleInRadian(angle);\n            const cos = Math.cos(radian);\n            const sin = Math.sin(radian);\n            const [scaleX, skewY, skewX, scaleY] = [cos, sin, -sin, cos];\n            if (isNumber(x) && isNumber(y)) {\n                const [a, b, c, d] = this.$matrix;\n                const { width, height } = this.getBoundingClientRect();\n                const originX = width / 2;\n                const originY = height / 2;\n                const moveX = x - originX;\n                const moveY = y - originY;\n                const translateX = ((moveX * d) - (c * moveY)) / ((a * d) - (c * b));\n                const translateY = ((moveY * a) - (b * moveX)) / ((a * d) - (c * b));\n                /**\n                 * Equals to\n                 * this.$translate(translateX, translateX);\n                 * this.$rotate(angle);\n                 * this.$translate(-translateX, -translateX);\n                 */\n                this.$transform(scaleX, skewY, skewX, scaleY, translateX * (1 - scaleX) - translateY * skewX, translateY * (1 - scaleY) - translateX * skewY);\n            }\n            else {\n                this.$transform(scaleX, skewY, skewX, scaleY, 0, 0);\n            }\n        }\n        return this;\n    }\n    /**\n     * Zooms the image.\n     * @param {number} scale The zoom factor. Positive numbers for zooming in, and negative numbers for zooming out.\n     * @param {number} [x] The zoom origin in the horizontal, defaults to the center of the image.\n     * @param {number} [y] The zoom origin in the vertical, defaults to the center of the image.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $zoom(scale, x, y) {\n        if (!this.scalable || scale === 0) {\n            return this;\n        }\n        if (scale < 0) {\n            scale = 1 / (1 - scale);\n        }\n        else {\n            scale += 1;\n        }\n        if (isNumber(x) && isNumber(y)) {\n            const [a, b, c, d] = this.$matrix;\n            const { width, height } = this.getBoundingClientRect();\n            const originX = width / 2;\n            const originY = height / 2;\n            const moveX = x - originX;\n            const moveY = y - originY;\n            const translateX = ((moveX * d) - (c * moveY)) / ((a * d) - (c * b));\n            const translateY = ((moveY * a) - (b * moveX)) / ((a * d) - (c * b));\n            /**\n             * Equals to\n             * this.$translate(translateX, translateX);\n             * this.$scale(scale);\n             * this.$translate(-translateX, -translateX);\n             */\n            this.$transform(scale, 0, 0, scale, translateX * (1 - scale), translateY * (1 - scale));\n        }\n        else {\n            this.$scale(scale);\n        }\n        return this;\n    }\n    /**\n     * Scales the image.\n     * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale}\n     * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/scale}\n     * @param {number} x The scaling factor in the horizontal direction.\n     * @param {number} [y] The scaling factor in the vertical direction.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $scale(x, y = x) {\n        if (this.scalable) {\n            this.$transform(x, 0, 0, y, 0, 0);\n        }\n        return this;\n    }\n    /**\n     * Skews the image.\n     * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/skew}\n     * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/transform}\n     * @param {number|string} x The skewing angle in the horizontal direction.\n     * @param {number|string} [y] The skewing angle in the vertical direction.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $skew(x, y = 0) {\n        if (this.skewable) {\n            const radianX = toAngleInRadian(x);\n            const radianY = toAngleInRadian(y);\n            this.$transform(1, Math.tan(radianY), Math.tan(radianX), 1, 0, 0);\n        }\n        return this;\n    }\n    /**\n     * Translates the image.\n     * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/translate}\n     * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/translate}\n     * @param {number} x The translating distance in the horizontal direction.\n     * @param {number} [y] The translating distance in the vertical direction.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $translate(x, y = x) {\n        if (this.translatable && isNumber(x) && isNumber(y)) {\n            this.$transform(1, 0, 0, 1, x, y);\n        }\n        return this;\n    }\n    /**\n     * Transforms the image.\n     * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix}\n     * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/transform}\n     * @param {number} a The scaling factor in the horizontal direction.\n     * @param {number} b The skewing angle in the vertical direction.\n     * @param {number} c The skewing angle in the horizontal direction.\n     * @param {number} d The scaling factor in the vertical direction.\n     * @param {number} e The translating distance in the horizontal direction.\n     * @param {number} f The translating distance in the vertical direction.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $transform(a, b, c, d, e, f) {\n        if (isNumber(a)\n            && isNumber(b)\n            && isNumber(c)\n            && isNumber(d)\n            && isNumber(e)\n            && isNumber(f)) {\n            return this.$setTransform(multiplyMatrices(this.$matrix, [a, b, c, d, e, f]));\n        }\n        return this;\n    }\n    /**\n     * Resets (overrides) the current transform to the specific identity matrix.\n     * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform}\n     * @param {number|Array} a The scaling factor in the horizontal direction.\n     * @param {number} b The skewing angle in the vertical direction.\n     * @param {number} c The skewing angle in the horizontal direction.\n     * @param {number} d The scaling factor in the vertical direction.\n     * @param {number} e The translating distance in the horizontal direction.\n     * @param {number} f The translating distance in the vertical direction.\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $setTransform(a, b, c, d, e, f) {\n        if (this.rotatable || this.scalable || this.skewable || this.translatable) {\n            if (Array.isArray(a)) {\n                [a, b, c, d, e, f] = a;\n            }\n            if (isNumber(a)\n                && isNumber(b)\n                && isNumber(c)\n                && isNumber(d)\n                && isNumber(e)\n                && isNumber(f)) {\n                const oldMatrix = [...this.$matrix];\n                const newMatrix = [a, b, c, d, e, f];\n                if (this.$emit(EVENT_TRANSFORM, {\n                    matrix: newMatrix,\n                    oldMatrix,\n                }) === false) {\n                    return this;\n                }\n                this.$matrix = newMatrix;\n                this.style.transform = `matrix(${newMatrix.join(', ')})`;\n            }\n        }\n        return this;\n    }\n    /**\n     * Retrieves the current transformation matrix being applied to the element.\n     * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getTransform}\n     * @returns {Array} Returns the readonly transformation matrix.\n     */\n    $getTransform() {\n        return this.$matrix.slice();\n    }\n    /**\n     * Resets the current transform to the initial identity matrix.\n     * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/resetTransform}\n     * @returns {CropperImage} Returns `this` for chaining.\n     */\n    $resetTransform() {\n        return this.$setTransform([1, 0, 0, 1, 0, 0]);\n    }\n}\nCropperImage.$name = CROPPER_IMAGE;\nCropperImage.$version = '2.0.0';\n\nexport { CropperImage as default };\n","import CropperElement from '@cropper/element';\nimport { CROPPER_HANDLE, ACTION_NONE } from '@cropper/utils';\n\nvar style = `:host{background-color:var(--theme-color);display:block}:host([action=move]),:host([action=select]){height:100%;left:0;position:absolute;top:0;width:100%}:host([action=move]){cursor:move}:host([action=select]){cursor:crosshair}:host([action$=-resize]){background-color:transparent;height:15px;position:absolute;width:15px}:host([action$=-resize]):after{background-color:var(--theme-color);content:\"\";display:block;height:5px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:5px}:host([action=n-resize]),:host([action=s-resize]){cursor:ns-resize;left:50%;transform:translateX(-50%);width:100%}:host([action=n-resize]){top:-8px}:host([action=s-resize]){bottom:-8px}:host([action=e-resize]),:host([action=w-resize]){cursor:ew-resize;height:100%;top:50%;transform:translateY(-50%)}:host([action=e-resize]){right:-8px}:host([action=w-resize]){left:-8px}:host([action=ne-resize]){cursor:nesw-resize;right:-8px;top:-8px}:host([action=nw-resize]){cursor:nwse-resize;left:-8px;top:-8px}:host([action=se-resize]){bottom:-8px;cursor:nwse-resize;right:-8px}:host([action=se-resize]):after{height:15px;width:15px}@media (pointer:coarse){:host([action=se-resize]):after{height:10px;width:10px}}@media (pointer:fine){:host([action=se-resize]):after{height:5px;width:5px}}:host([action=sw-resize]){bottom:-8px;cursor:nesw-resize;left:-8px}:host([plain]){background-color:transparent}`;\n\nclass CropperHandle extends CropperElement {\n    constructor() {\n        super(...arguments);\n        this.$onCanvasCropEnd = null;\n        this.$onCanvasCropStart = null;\n        this.$style = style;\n        this.action = ACTION_NONE;\n        this.plain = false;\n        this.slottable = false;\n        this.themeColor = 'rgba(51, 153, 255, 0.5)';\n    }\n    static get observedAttributes() {\n        return super.observedAttributes.concat([\n            'action',\n            'plain',\n        ]);\n    }\n}\nCropperHandle.$name = CROPPER_HANDLE;\nCropperHandle.$version = '2.0.0';\n\nexport { CropperHandle as default };\n","import CropperElement from '@cropper/element';\nimport { CROPPER_SELECTION, EVENT_CHANGE, on, EVENT_KEYDOWN, off, isPositiveNumber, CROPPER_CANVAS, EVENT_ACTION_START, EVENT_ACTION_END, EVENT_ACTION, getAdjustedSizes, ACTION_SELECT, ACTION_SCALE, getOffset, ACTION_MOVE, ACTION_RESIZE_NORTHWEST, ACTION_RESIZE_SOUTHWEST, ACTION_RESIZE_NORTHEAST, ACTION_RESIZE_SOUTHEAST, isNumber, isPlainObject, CROPPER_IMAGE, isFunction, ACTION_RESIZE_WEST, ACTION_RESIZE_EAST, ACTION_RESIZE_SOUTH, ACTION_RESIZE_NORTH } from '@cropper/utils';\n\nvar style = `:host{display:block;left:0;position:relative;right:0}:host([outlined]){outline:1px solid var(--theme-color)}:host([multiple]){outline:1px dashed hsla(0,0%,100%,.5)}:host([multiple]):after{bottom:0;content:\"\";cursor:pointer;display:block;left:0;position:absolute;right:0;top:0}:host([multiple][active]){outline-color:var(--theme-color);z-index:1}:host([multiple])>*{visibility:hidden}:host([multiple][active])>*{visibility:visible}:host([multiple][active]):after{display:none}`;\n\nconst canvasCache = new WeakMap();\nclass CropperSelection extends CropperElement {\n    constructor() {\n        super(...arguments);\n        this.$onCanvasAction = null;\n        this.$onCanvasActionStart = null;\n        this.$onCanvasActionEnd = null;\n        this.$onDocumentKeyDown = null;\n        this.$action = '';\n        this.$actionStartTarget = null;\n        this.$changing = false;\n        this.$style = style;\n        this.$initialSelection = {\n            x: 0,\n            y: 0,\n            width: 0,\n            height: 0,\n        };\n        this.x = 0;\n        this.y = 0;\n        this.width = 0;\n        this.height = 0;\n        this.aspectRatio = NaN;\n        this.initialAspectRatio = NaN;\n        this.initialCoverage = NaN;\n        this.active = false;\n        // Deprecated as of v2.0.0-rc.0, use `dynamic` instead.\n        this.linked = false;\n        this.dynamic = false;\n        this.movable = false;\n        this.resizable = false;\n        this.zoomable = false;\n        this.multiple = false;\n        this.keyboard = false;\n        this.outlined = false;\n        this.precise = false;\n    }\n    set $canvas(element) {\n        canvasCache.set(this, element);\n    }\n    get $canvas() {\n        return canvasCache.get(this);\n    }\n    static get observedAttributes() {\n        return super.observedAttributes.concat([\n            'active',\n            'aspect-ratio',\n            'dynamic',\n            'height',\n            'initial-aspect-ratio',\n            'initial-coverage',\n            'keyboard',\n            'linked',\n            'movable',\n            'multiple',\n            'outlined',\n            'precise',\n            'resizable',\n            'width',\n            'x',\n            'y',\n            'zoomable',\n        ]);\n    }\n    $propertyChangedCallback(name, oldValue, newValue) {\n        if (Object.is(newValue, oldValue)) {\n            return;\n        }\n        super.$propertyChangedCallback(name, oldValue, newValue);\n        switch (name) {\n            case 'x':\n            case 'y':\n            case 'width':\n            case 'height':\n                if (!this.$changing) {\n                    this.$nextTick(() => {\n                        this.$change(this.x, this.y, this.width, this.height, this.aspectRatio, true);\n                    });\n                }\n                break;\n            case 'aspectRatio':\n            case 'initialAspectRatio':\n                this.$nextTick(() => {\n                    this.$initSelection();\n                });\n                break;\n            case 'initialCoverage':\n                this.$nextTick(() => {\n                    if (isPositiveNumber(newValue) && newValue <= 1) {\n                        this.$initSelection(true, true);\n                    }\n                });\n                break;\n            case 'keyboard':\n                this.$nextTick(() => {\n                    if (this.$canvas) {\n                        if (newValue) {\n                            if (!this.$onDocumentKeyDown) {\n                                this.$onDocumentKeyDown = this.$handleKeyDown.bind(this);\n                                on(this.ownerDocument, EVENT_KEYDOWN, this.$onDocumentKeyDown);\n                            }\n                        }\n                        else if (this.$onDocumentKeyDown) {\n                            off(this.ownerDocument, EVENT_KEYDOWN, this.$onDocumentKeyDown);\n                            this.$onDocumentKeyDown = null;\n                        }\n                    }\n                });\n                break;\n            case 'multiple':\n                this.$nextTick(() => {\n                    if (this.$canvas) {\n                        const selections = this.$getSelections();\n                        if (newValue) {\n                            selections.forEach((selection) => {\n                                selection.active = false;\n                            });\n                            this.active = true;\n                            this.$emit(EVENT_CHANGE, {\n                                x: this.x,\n                                y: this.y,\n                                width: this.width,\n                                height: this.height,\n                            });\n                        }\n                        else {\n                            this.active = false;\n                            selections.slice(1).forEach((selection) => {\n                                this.$removeSelection(selection);\n                            });\n                        }\n                    }\n                });\n                break;\n            case 'precise':\n                this.$nextTick(() => {\n                    this.$change(this.x, this.y);\n                });\n                break;\n            // Backwards compatible with 2.0.0-rc\n            case 'linked':\n                if (newValue) {\n                    this.dynamic = true;\n                }\n                break;\n        }\n    }\n    connectedCallback() {\n        super.connectedCallback();\n        const $canvas = this.closest(this.$getTagNameOf(CROPPER_CANVAS));\n        if ($canvas) {\n            this.$canvas = $canvas;\n            this.$setStyles({\n                position: 'absolute',\n                transform: `translate(${this.x}px, ${this.y}px)`,\n            });\n            if (!this.hidden) {\n                this.$render();\n            }\n            this.$initSelection(true);\n            this.$onCanvasActionStart = this.$handleActionStart.bind(this);\n            this.$onCanvasActionEnd = this.$handleActionEnd.bind(this);\n            this.$onCanvasAction = this.$handleAction.bind(this);\n            on($canvas, EVENT_ACTION_START, this.$onCanvasActionStart);\n            on($canvas, EVENT_ACTION_END, this.$onCanvasActionEnd);\n            on($canvas, EVENT_ACTION, this.$onCanvasAction);\n        }\n        else {\n            this.$render();\n        }\n    }\n    disconnectedCallback() {\n        const { $canvas } = this;\n        if ($canvas) {\n            if (this.$onCanvasActionStart) {\n                off($canvas, EVENT_ACTION_START, this.$onCanvasActionStart);\n                this.$onCanvasActionStart = null;\n            }\n            if (this.$onCanvasActionEnd) {\n                off($canvas, EVENT_ACTION_END, this.$onCanvasActionEnd);\n                this.$onCanvasActionEnd = null;\n            }\n            if (this.$onCanvasAction) {\n                off($canvas, EVENT_ACTION, this.$onCanvasAction);\n                this.$onCanvasAction = null;\n            }\n        }\n        super.disconnectedCallback();\n    }\n    $getSelections() {\n        let selections = [];\n        if (this.parentElement) {\n            selections = Array.from(this.parentElement.querySelectorAll(this.$getTagNameOf(CROPPER_SELECTION)));\n        }\n        return selections;\n    }\n    $initSelection(center = false, resize = false) {\n        const { initialCoverage, parentElement } = this;\n        if (isPositiveNumber(initialCoverage) && parentElement) {\n            const aspectRatio = this.aspectRatio || this.initialAspectRatio;\n            let width = (resize ? 0 : this.width) || parentElement.offsetWidth * initialCoverage;\n            let height = (resize ? 0 : this.height) || parentElement.offsetHeight * initialCoverage;\n            if (isPositiveNumber(aspectRatio)) {\n                ({ width, height } = getAdjustedSizes({ aspectRatio, width, height }));\n            }\n            this.$change(this.x, this.y, width, height);\n            if (center) {\n                this.$center();\n            }\n            // Overrides the initial position and size\n            this.$initialSelection = {\n                x: this.x,\n                y: this.y,\n                width: this.width,\n                height: this.height,\n            };\n        }\n    }\n    $createSelection() {\n        const newSelection = this.cloneNode(true);\n        if (this.hasAttribute('id')) {\n            newSelection.removeAttribute('id');\n        }\n        newSelection.initialCoverage = NaN;\n        this.active = false;\n        if (this.parentElement) {\n            this.parentElement.insertBefore(newSelection, this.nextSibling);\n        }\n        return newSelection;\n    }\n    $removeSelection(selection = this) {\n        if (this.parentElement) {\n            const selections = this.$getSelections();\n            if (selections.length > 1) {\n                const index = selections.indexOf(selection);\n                const activeSelection = selections[index + 1] || selections[index - 1];\n                if (activeSelection) {\n                    selection.active = false;\n                    this.parentElement.removeChild(selection);\n                    activeSelection.active = true;\n                    activeSelection.$emit(EVENT_CHANGE, {\n                        x: activeSelection.x,\n                        y: activeSelection.y,\n                        width: activeSelection.width,\n                        height: activeSelection.height,\n                    });\n                }\n            }\n            else {\n                this.$clear();\n            }\n        }\n    }\n    $handleActionStart(event) {\n        var _a, _b;\n        const relatedTarget = (_b = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.relatedEvent) === null || _b === void 0 ? void 0 : _b.target;\n        this.$action = '';\n        this.$actionStartTarget = relatedTarget;\n        if (!this.hidden\n            && this.multiple\n            && !this.active\n            && relatedTarget === this\n            && this.parentElement) {\n            this.$getSelections().forEach((selection) => {\n                selection.active = false;\n            });\n            this.active = true;\n            this.$emit(EVENT_CHANGE, {\n                x: this.x,\n                y: this.y,\n                width: this.width,\n                height: this.height,\n            });\n        }\n    }\n    $handleAction(event) {\n        const { currentTarget, detail } = event;\n        if (!currentTarget || !detail) {\n            return;\n        }\n        const { relatedEvent } = detail;\n        let { action } = detail;\n        // Switching to another selection\n        if (!action && this.multiple) {\n            // Get the `action` property from the focusing in selection\n            action = this.$action || (relatedEvent === null || relatedEvent === void 0 ? void 0 : relatedEvent.target.action);\n            this.$action = action;\n        }\n        if (!action\n            || (this.hidden && action !== ACTION_SELECT)\n            || (this.multiple && !this.active && action !== ACTION_SCALE)) {\n            return;\n        }\n        const moveX = detail.endX - detail.startX;\n        const moveY = detail.endY - detail.startY;\n        const { width, height } = this;\n        let { aspectRatio } = this;\n        // Locking aspect ratio by holding shift key\n        if (!isPositiveNumber(aspectRatio) && relatedEvent.shiftKey) {\n            aspectRatio = isPositiveNumber(width) && isPositiveNumber(height) ? width / height : 1;\n        }\n        switch (action) {\n            case ACTION_SELECT:\n                if (moveX !== 0 && moveY !== 0) {\n                    const { $canvas } = this;\n                    const offset = getOffset(currentTarget);\n                    (this.multiple && !this.hidden ? this.$createSelection() : this).$change(detail.startX - offset.left, detail.startY - offset.top, Math.abs(moveX), Math.abs(moveY), aspectRatio);\n                    if (moveX < 0) {\n                        if (moveY < 0) {\n                            // ↖️\n                            action = ACTION_RESIZE_NORTHWEST;\n                        }\n                        else if (moveY > 0) {\n                            // ↙️\n                            action = ACTION_RESIZE_SOUTHWEST;\n                        }\n                    }\n                    else if (moveX > 0) {\n                        if (moveY < 0) {\n                            // ↗️\n                            action = ACTION_RESIZE_NORTHEAST;\n                        }\n                        else if (moveY > 0) {\n                            // ↘️\n                            action = ACTION_RESIZE_SOUTHEAST;\n                        }\n                    }\n                    if ($canvas) {\n                        $canvas.$action = action;\n                    }\n                }\n                break;\n            case ACTION_MOVE:\n                if (this.movable && (this.dynamic\n                    || (this.$actionStartTarget && this.contains(this.$actionStartTarget)))) {\n                    this.$move(moveX, moveY);\n                }\n                break;\n            case ACTION_SCALE:\n                if (relatedEvent && this.zoomable && (this.dynamic\n                    || this.contains(relatedEvent.target))) {\n                    const offset = getOffset(currentTarget);\n                    this.$zoom(detail.scale, relatedEvent.pageX - offset.left, relatedEvent.pageY - offset.top);\n                }\n                break;\n            default:\n                this.$resize(action, moveX, moveY, aspectRatio);\n        }\n    }\n    $handleActionEnd() {\n        this.$action = '';\n        this.$actionStartTarget = null;\n    }\n    $handleKeyDown(event) {\n        if (this.hidden\n            || !this.keyboard\n            || (this.multiple && !this.active)\n            || event.defaultPrevented) {\n            return;\n        }\n        const { activeElement } = document;\n        // Disable keyboard control when input something\n        if (activeElement && (['INPUT', 'TEXTAREA'].includes(activeElement.tagName)\n            || ['true', 'plaintext-only'].includes(activeElement.contentEditable))) {\n            return;\n        }\n        switch (event.key) {\n            case 'Backspace':\n                if (event.metaKey) {\n                    event.preventDefault();\n                    this.$removeSelection();\n                }\n                break;\n            case 'Delete':\n                event.preventDefault();\n                this.$removeSelection();\n                break;\n            // Move to the left\n            case 'ArrowLeft':\n                event.preventDefault();\n                this.$move(-1, 0);\n                break;\n            // Move to the right\n            case 'ArrowRight':\n                event.preventDefault();\n                this.$move(1, 0);\n                break;\n            // Move to the top\n            case 'ArrowUp':\n                event.preventDefault();\n                this.$move(0, -1);\n                break;\n            // Move to the bottom\n            case 'ArrowDown':\n                event.preventDefault();\n                this.$move(0, 1);\n                break;\n            case '+':\n                event.preventDefault();\n                this.$zoom(0.1);\n                break;\n            case '-':\n                event.preventDefault();\n                this.$zoom(-0.1);\n                break;\n        }\n    }\n    /**\n     * Aligns the selection to the center of its parent element.\n     * @returns {CropperSelection} Returns `this` for chaining.\n     */\n    $center() {\n        const { parentElement } = this;\n        if (!parentElement) {\n            return this;\n        }\n        const x = (parentElement.offsetWidth - this.width) / 2;\n        const y = (parentElement.offsetHeight - this.height) / 2;\n        return this.$change(x, y);\n    }\n    /**\n     * Moves the selection.\n     * @param {number} x The moving distance in the horizontal direction.\n     * @param {number} [y] The moving distance in the vertical direction.\n     * @returns {CropperSelection} Returns `this` for chaining.\n     */\n    $move(x, y = x) {\n        return this.$moveTo(this.x + x, this.y + y);\n    }\n    /**\n     * Moves the selection to a specific position.\n     * @param {number} x The new position in the horizontal direction.\n     * @param {number} [y] The new position in the vertical direction.\n     * @returns {CropperSelection} Returns `this` for chaining.\n     */\n    $moveTo(x, y = x) {\n        if (!this.movable) {\n            return this;\n        }\n        return this.$change(x, y);\n    }\n    /**\n     * Adjusts the size the selection on a specific side or corner.\n     * @param {string} action Indicates the side or corner to resize.\n     * @param {number} [offsetX] The horizontal offset of the specific side or corner.\n     * @param {number} [offsetY] The vertical offset of the specific side or corner.\n     * @param {number} [aspectRatio] The aspect ratio for computing the new size if it is necessary.\n     * @returns {CropperSelection} Returns `this` for chaining.\n     */\n    $resize(action, offsetX = 0, offsetY = 0, aspectRatio = this.aspectRatio) {\n        if (!this.resizable) {\n            return this;\n        }\n        const hasValidAspectRatio = isPositiveNumber(aspectRatio);\n        const { $canvas } = this;\n        let { x, y, width, height, } = this;\n        switch (action) {\n            case ACTION_RESIZE_NORTH:\n                y += offsetY;\n                height -= offsetY;\n                if (height < 0) {\n                    action = ACTION_RESIZE_SOUTH;\n                    height = -height;\n                    y -= height;\n                }\n                if (hasValidAspectRatio) {\n                    offsetX = offsetY * aspectRatio;\n                    x += offsetX / 2;\n                    width -= offsetX;\n                    if (width < 0) {\n                        width = -width;\n                        x -= width;\n                    }\n                }\n                break;\n            case ACTION_RESIZE_EAST:\n                width += offsetX;\n                if (width < 0) {\n                    action = ACTION_RESIZE_WEST;\n                    width = -width;\n                    x -= width;\n                }\n                if (hasValidAspectRatio) {\n                    offsetY = offsetX / aspectRatio;\n                    y -= offsetY / 2;\n                    height += offsetY;\n                    if (height < 0) {\n                        height = -height;\n                        y -= height;\n                    }\n                }\n                break;\n            case ACTION_RESIZE_SOUTH:\n                height += offsetY;\n                if (height < 0) {\n                    action = ACTION_RESIZE_NORTH;\n                    height = -height;\n                    y -= height;\n                }\n                if (hasValidAspectRatio) {\n                    offsetX = offsetY * aspectRatio;\n                    x -= offsetX / 2;\n                    width += offsetX;\n                    if (width < 0) {\n                        width = -width;\n                        x -= width;\n                    }\n                }\n                break;\n            case ACTION_RESIZE_WEST:\n                x += offsetX;\n                width -= offsetX;\n                if (width < 0) {\n                    action = ACTION_RESIZE_EAST;\n                    width = -width;\n                    x -= width;\n                }\n                if (hasValidAspectRatio) {\n                    offsetY = offsetX / aspectRatio;\n                    y += offsetY / 2;\n                    height -= offsetY;\n                    if (height < 0) {\n                        height = -height;\n                        y -= height;\n                    }\n                }\n                break;\n            case ACTION_RESIZE_NORTHEAST:\n                if (hasValidAspectRatio) {\n                    offsetY = -offsetX / aspectRatio;\n                }\n                y += offsetY;\n                height -= offsetY;\n                width += offsetX;\n                if (width < 0 && height < 0) {\n                    action = ACTION_RESIZE_SOUTHWEST;\n                    width = -width;\n                    height = -height;\n                    x -= width;\n                    y -= height;\n                }\n                else if (width < 0) {\n                    action = ACTION_RESIZE_NORTHWEST;\n                    width = -width;\n                    x -= width;\n                }\n                else if (height < 0) {\n                    action = ACTION_RESIZE_SOUTHEAST;\n                    height = -height;\n                    y -= height;\n                }\n                break;\n            case ACTION_RESIZE_NORTHWEST:\n                if (hasValidAspectRatio) {\n                    offsetY = offsetX / aspectRatio;\n                }\n                x += offsetX;\n                y += offsetY;\n                width -= offsetX;\n                height -= offsetY;\n                if (width < 0 && height < 0) {\n                    action = ACTION_RESIZE_SOUTHEAST;\n                    width = -width;\n                    height = -height;\n                    x -= width;\n                    y -= height;\n                }\n                else if (width < 0) {\n                    action = ACTION_RESIZE_NORTHEAST;\n                    width = -width;\n                    x -= width;\n                }\n                else if (height < 0) {\n                    action = ACTION_RESIZE_SOUTHWEST;\n                    height = -height;\n                    y -= height;\n                }\n                break;\n            case ACTION_RESIZE_SOUTHEAST:\n                if (hasValidAspectRatio) {\n                    offsetY = offsetX / aspectRatio;\n                }\n                width += offsetX;\n                height += offsetY;\n                if (width < 0 && height < 0) {\n                    action = ACTION_RESIZE_NORTHWEST;\n                    width = -width;\n                    height = -height;\n                    x -= width;\n                    y -= height;\n                }\n                else if (width < 0) {\n                    action = ACTION_RESIZE_SOUTHWEST;\n                    width = -width;\n                    x -= width;\n                }\n                else if (height < 0) {\n                    action = ACTION_RESIZE_NORTHEAST;\n                    height = -height;\n                    y -= height;\n                }\n                break;\n            case ACTION_RESIZE_SOUTHWEST:\n                if (hasValidAspectRatio) {\n                    offsetY = -offsetX / aspectRatio;\n                }\n                x += offsetX;\n                width -= offsetX;\n                height += offsetY;\n                if (width < 0 && height < 0) {\n                    action = ACTION_RESIZE_NORTHEAST;\n                    width = -width;\n                    height = -height;\n                    x -= width;\n                    y -= height;\n                }\n                else if (width < 0) {\n                    action = ACTION_RESIZE_SOUTHEAST;\n                    width = -width;\n                    x -= width;\n                }\n                else if (height < 0) {\n                    action = ACTION_RESIZE_NORTHWEST;\n                    height = -height;\n                    y -= height;\n                }\n                break;\n        }\n        if ($canvas) {\n            $canvas.$setAction(action);\n        }\n        return this.$change(x, y, width, height);\n    }\n    /**\n     * Zooms the selection.\n     * @param {number} scale The zoom factor. Positive numbers for zooming in, and negative numbers for zooming out.\n     * @param {number} [x] The zoom origin in the horizontal, defaults to the center of the selection.\n     * @param {number} [y] The zoom origin in the vertical, defaults to the center of the selection.\n     * @returns {CropperSelection} Returns `this` for chaining.\n     */\n    $zoom(scale, x, y) {\n        if (!this.zoomable || scale === 0) {\n            return this;\n        }\n        if (scale < 0) {\n            scale = 1 / (1 - scale);\n        }\n        else {\n            scale += 1;\n        }\n        const { width, height } = this;\n        const newWidth = width * scale;\n        const newHeight = height * scale;\n        let newX = this.x;\n        let newY = this.y;\n        if (isNumber(x) && isNumber(y)) {\n            newX -= (newWidth - width) * ((x - this.x) / width);\n            newY -= (newHeight - height) * ((y - this.y) / height);\n        }\n        else {\n            // Zoom from the center of the selection\n            newX -= (newWidth - width) / 2;\n            newY -= (newHeight - height) / 2;\n        }\n        return this.$change(newX, newY, newWidth, newHeight);\n    }\n    /**\n     * Changes the position and/or size of the selection.\n     * @param {number} x The new position in the horizontal direction.\n     * @param {number} y The new position in the vertical direction.\n     * @param {number} [width] The new width.\n     * @param {number} [height] The new height.\n     * @param {number} [aspectRatio] The new aspect ratio for this change only.\n     * @param {number} [_force] Force change.\n     * @returns {CropperSelection} Returns `this` for chaining.\n     */\n    $change(x, y, width = this.width, height = this.height, aspectRatio = this.aspectRatio, _force = false) {\n        if (this.$changing\n            || !isNumber(x)\n            || !isNumber(y)\n            || !isNumber(width)\n            || !isNumber(height)\n            || width < 0\n            || height < 0) {\n            return this;\n        }\n        if (isPositiveNumber(aspectRatio)) {\n            ({ width, height } = getAdjustedSizes({ aspectRatio, width, height }, 'cover'));\n        }\n        if (!this.precise) {\n            x = Math.round(x);\n            y = Math.round(y);\n            width = Math.round(width);\n            height = Math.round(height);\n        }\n        if (x === this.x\n            && y === this.y\n            && width === this.width\n            && height === this.height\n            && Object.is(aspectRatio, this.aspectRatio)\n            && !_force) {\n            return this;\n        }\n        if (this.hidden) {\n            this.hidden = false;\n        }\n        if (this.$emit(EVENT_CHANGE, {\n            x,\n            y,\n            width,\n            height,\n        }) === false) {\n            return this;\n        }\n        this.$changing = true;\n        this.x = x;\n        this.y = y;\n        this.width = width;\n        this.height = height;\n        this.$changing = false;\n        return this.$render();\n    }\n    /**\n     * Resets the selection to its initial position and size.\n     * @returns {CropperSelection} Returns `this` for chaining.\n     */\n    $reset() {\n        const { x, y, width, height, } = this.$initialSelection;\n        return this.$change(x, y, width, height);\n    }\n    /**\n     * Clears the selection.\n     * @returns {CropperSelection} Returns `this` for chaining.\n     */\n    $clear() {\n        this.$change(0, 0, 0, 0, NaN, true);\n        this.hidden = true;\n        return this;\n    }\n    /**\n     * Refreshes the position or size of the selection.\n     * @returns {CropperSelection} Returns `this` for chaining.\n     */\n    $render() {\n        return this.$setStyles({\n            transform: `translate(${this.x}px, ${this.y}px)`,\n            width: this.width,\n            height: this.height,\n        });\n    }\n    /**\n     * Generates a real canvas element, with the image (selected area only) draw into if there is one.\n     * @param {object} [options] The available options.\n     * @param {number} [options.width] The width of the canvas.\n     * @param {number} [options.height] The height of the canvas.\n     * @param {Function} [options.beforeDraw] The function called before drawing the image onto the canvas.\n     * @returns {Promise} Returns a promise that resolves to the generated canvas element.\n     */\n    $toCanvas(options) {\n        return new Promise((resolve, reject) => {\n            if (!this.isConnected) {\n                reject(new Error('The current element is not connected to the DOM.'));\n                return;\n            }\n            const canvas = document.createElement('canvas');\n            let { width, height } = this;\n            let scale = 1;\n            if (isPlainObject(options)\n                && (isPositiveNumber(options.width) || isPositiveNumber(options.height))) {\n                ({ width, height } = getAdjustedSizes({\n                    aspectRatio: width / height,\n                    width: options.width,\n                    height: options.height,\n                }));\n                scale = width / this.width;\n            }\n            canvas.width = width;\n            canvas.height = height;\n            if (!this.$canvas) {\n                resolve(canvas);\n                return;\n            }\n            const cropperImage = this.$canvas.querySelector(this.$getTagNameOf(CROPPER_IMAGE));\n            if (!cropperImage) {\n                resolve(canvas);\n                return;\n            }\n            cropperImage.$ready().then((image) => {\n                const context = canvas.getContext('2d');\n                if (context) {\n                    const [a, b, c, d, e, f] = cropperImage.$getTransform();\n                    const offsetX = -this.x;\n                    const offsetY = -this.y;\n                    const translateX = ((offsetX * d) - (c * offsetY)) / ((a * d) - (c * b));\n                    const translateY = ((offsetY * a) - (b * offsetX)) / ((a * d) - (c * b));\n                    let newE = a * translateX + c * translateY + e;\n                    let newF = b * translateX + d * translateY + f;\n                    let destWidth = image.naturalWidth;\n                    let destHeight = image.naturalHeight;\n                    if (scale !== 1) {\n                        newE *= scale;\n                        newF *= scale;\n                        destWidth *= scale;\n                        destHeight *= scale;\n                    }\n                    const centerX = destWidth / 2;\n                    const centerY = destHeight / 2;\n                    context.fillStyle = 'transparent';\n                    context.fillRect(0, 0, width, height);\n                    if (isPlainObject(options) && isFunction(options.beforeDraw)) {\n                        options.beforeDraw.call(this, context, canvas);\n                    }\n                    context.save();\n                    // Move the transform origin to the center of the image.\n                    // https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin\n                    context.translate(centerX, centerY);\n                    context.transform(a, b, c, d, newE, newF);\n                    // Move the transform origin to the top-left of the image.\n                    context.translate(-centerX, -centerY);\n                    context.drawImage(image, 0, 0, destWidth, destHeight);\n                    context.restore();\n                }\n                resolve(canvas);\n            }).catch(reject);\n        });\n    }\n}\nCropperSelection.$name = CROPPER_SELECTION;\nCropperSelection.$version = '2.0.0';\n\nexport { CropperSelection as default };\n","import CropperElement from '@cropper/element';\nimport { CROPPER_CROSSHAIR } from '@cropper/utils';\n\nvar style = `:host{display:inline-block;height:1em;position:relative;touch-action:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:1em}:host:after,:host:before{background-color:var(--theme-color);content:\"\";display:block;position:absolute}:host:before{height:1px;left:0;top:50%;transform:translateY(-50%);width:100%}:host:after{height:100%;left:50%;top:0;transform:translateX(-50%);width:1px}:host([centered]){left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}`;\n\nclass CropperCrosshair extends CropperElement {\n    constructor() {\n        super(...arguments);\n        this.$style = style;\n        this.centered = false;\n        this.slottable = false;\n        this.themeColor = 'rgba(238, 238, 238, 0.5)';\n    }\n    static get observedAttributes() {\n        return super.observedAttributes.concat([\n            'centered',\n        ]);\n    }\n}\nCropperCrosshair.$name = CROPPER_CROSSHAIR;\nCropperCrosshair.$version = '2.0.0';\n\nexport { CropperCrosshair as default };\n","import CropperElement from '@cropper/element';\nimport { CROPPER_SHADE, CROPPER_CANVAS, CROPPER_SELECTION, ACTION_SELECT, on, EVENT_ACTION_START, EVENT_ACTION_END, EVENT_CHANGE, off, isNumber, WINDOW } from '@cropper/utils';\n\nvar style = `:host{display:block;height:0;left:0;outline:var(--theme-color) solid 1px;position:relative;top:0;width:0}:host([transparent]){outline-color:transparent}`;\n\nconst canvasCache = new WeakMap();\nclass CropperShade extends CropperElement {\n    constructor() {\n        super(...arguments);\n        this.$onCanvasChange = null;\n        this.$onCanvasActionEnd = null;\n        this.$onCanvasActionStart = null;\n        this.$style = style;\n        this.x = 0;\n        this.y = 0;\n        this.width = 0;\n        this.height = 0;\n        this.slottable = false;\n        this.themeColor = 'rgba(0, 0, 0, 0.65)';\n    }\n    set $canvas(element) {\n        canvasCache.set(this, element);\n    }\n    get $canvas() {\n        return canvasCache.get(this);\n    }\n    static get observedAttributes() {\n        return super.observedAttributes.concat([\n            'height',\n            'width',\n            'x',\n            'y',\n        ]);\n    }\n    connectedCallback() {\n        super.connectedCallback();\n        const $canvas = this.closest(this.$getTagNameOf(CROPPER_CANVAS));\n        if ($canvas) {\n            this.$canvas = $canvas;\n            this.style.position = 'absolute';\n            const $selection = $canvas.querySelector(this.$getTagNameOf(CROPPER_SELECTION));\n            if ($selection) {\n                this.$onCanvasActionStart = (event) => {\n                    if ($selection.hidden && event.detail.action === ACTION_SELECT) {\n                        this.hidden = false;\n                    }\n                };\n                this.$onCanvasActionEnd = (event) => {\n                    if ($selection.hidden && event.detail.action === ACTION_SELECT) {\n                        this.hidden = true;\n                    }\n                };\n                this.$onCanvasChange = (event) => {\n                    const { x, y, width, height, } = event.detail;\n                    this.$change(x, y, width, height);\n                    if ($selection.hidden || (x === 0 && y === 0 && width === 0 && height === 0)) {\n                        this.hidden = true;\n                    }\n                };\n                on($canvas, EVENT_ACTION_START, this.$onCanvasActionStart);\n                on($canvas, EVENT_ACTION_END, this.$onCanvasActionEnd);\n                on($canvas, EVENT_CHANGE, this.$onCanvasChange);\n            }\n        }\n        this.$render();\n    }\n    disconnectedCallback() {\n        const { $canvas } = this;\n        if ($canvas) {\n            if (this.$onCanvasActionStart) {\n                off($canvas, EVENT_ACTION_START, this.$onCanvasActionStart);\n                this.$onCanvasActionStart = null;\n            }\n            if (this.$onCanvasActionEnd) {\n                off($canvas, EVENT_ACTION_END, this.$onCanvasActionEnd);\n                this.$onCanvasActionEnd = null;\n            }\n            if (this.$onCanvasChange) {\n                off($canvas, EVENT_CHANGE, this.$onCanvasChange);\n                this.$onCanvasChange = null;\n            }\n        }\n        super.disconnectedCallback();\n    }\n    /**\n     * Changes the position and/or size of the shade.\n     * @param {number} x The new position in the horizontal direction.\n     * @param {number} y The new position in the vertical direction.\n     * @param {number} [width] The new width.\n     * @param {number} [height] The new height.\n     * @returns {CropperShade} Returns `this` for chaining.\n     */\n    $change(x, y, width = this.width, height = this.height) {\n        if (!isNumber(x)\n            || !isNumber(y)\n            || !isNumber(width)\n            || !isNumber(height)\n            || (x === this.x && y === this.y && width === this.width && height === this.height)) {\n            return this;\n        }\n        if (this.hidden) {\n            this.hidden = false;\n        }\n        this.x = x;\n        this.y = y;\n        this.width = width;\n        this.height = height;\n        return this.$render();\n    }\n    /**\n     * Resets the shade to its initial position and size.\n     * @returns {CropperShade} Returns `this` for chaining.\n     */\n    $reset() {\n        return this.$change(0, 0, 0, 0);\n    }\n    /**\n     * Refreshes the position or size of the shade.\n     * @returns {CropperShade} Returns `this` for chaining.\n     */\n    $render() {\n        return this.$setStyles({\n            transform: `translate(${this.x}px, ${this.y}px)`,\n            width: this.width,\n            height: this.height,\n            outlineWidth: WINDOW.innerWidth,\n        });\n    }\n}\nCropperShade.$name = CROPPER_SHADE;\nCropperShade.$version = '2.0.0';\n\nexport { CropperShade as default };\n","import { localized, msg } from \"@lit/localize\"\nimport { html, LitElement } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\n\n@customElement(\"arrows-center-icon\")\n@localized()\nexport class ArrowsCenterIcon extends LitElement {\n  @property({ type: String }) color = \"currentColor\"\n  @property({ type: String }) size = \"24px\"\n\n  override render() {\n    return html`<svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      viewBox=\"0 0 122.88 109.78\"\n      fill=\"${this.color}\"\n      width=\"${this.size}\"\n      height=\"${this.size}\"\n    >\n      <title>${msg(\"Center icon\")}</title>\n      <path\n        d=\"M28.94,13.7l.09-.09,5.65-5.67.15-.13c2.61-2.4,5.24-1.62,6.76,1.44a1.59,1.59,0,0,1,.16.54c1.25,10.35,2.1,20.29,3.34,30.64.25,3.42-2.08,4.84-5.24,4.47l-28.21-3c-4.92-.58-7.36-3.84-3.42-7.78,1.78-1.77,3.54-3.58,5.34-5.32l-13-13a2,2,0,0,1,0-2.8L13,.58a2,2,0,0,1,2.81,0L28.94,13.7Zm32.5,27.58A13.61,13.61,0,1,1,47.83,54.89,13.61,13.61,0,0,1,61.44,41.28Zm32.5,54.8-.09.09-5.66,5.67a.86.86,0,0,1-.14.13c-2.61,2.4-5.24,1.62-6.76-1.44a1.58,1.58,0,0,1-.16-.55C79.88,89.64,79,79.7,77.79,69.35c-.25-3.42,2.07-4.84,5.24-4.47l28.21,3c4.92.58,7.36,3.84,3.42,7.78-1.78,1.77-3.54,3.58-5.34,5.32l13,13a2,2,0,0,1,0,2.8l-12.42,12.43a2,2,0,0,1-2.81,0L93.94,96.08Zm-65,0,.09.09,5.65,5.67.15.13c2.61,2.4,5.24,1.62,6.76-1.44a1.58,1.58,0,0,0,.16-.55C43,89.64,43.85,79.7,45.09,69.35c.25-3.42-2.08-4.84-5.24-4.47l-28.21,3c-4.92.58-7.36,3.84-3.42,7.78C10,77.44,11.76,79.25,13.56,81L.58,94a2,2,0,0,0,0,2.8L13,109.21a2,2,0,0,0,2.81,0L28.94,96.08Zm65-82.38-.09-.09L88.19,7.94a.86.86,0,0,0-.14-.13c-2.61-2.4-5.24-1.62-6.76,1.44a1.59,1.59,0,0,0-.16.54C79.88,20.14,79,30.08,77.79,40.43c-.25,3.42,2.07,4.84,5.24,4.47l28.21-3c4.92-.58,7.36-3.84,3.42-7.78-1.78-1.77-3.54-3.58-5.34-5.32l13-13a2,2,0,0,0,0-2.8L109.88.58a2,2,0,0,0-2.81,0L93.94,13.7Z\"\n      />\n    </svg>`\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"arrows-center-icon\": ArrowsCenterIcon\n  }\n}\n","import { css } from \"lit\"\nimport {\n  SAFE_BLUE,\n  SAFE_CAPPUCINO,\n  SAFE_CHOCOLATE,\n  SAFE_DARKER_WHITE,\n  SAFE_GREY,\n  SAFE_LIGHT_BLACK,\n} from \"../utils/colors\"\n\nexport const TEXTAREA = css`\n  .textarea {\n    width: 100%;\n    min-height: 10px;\n    background-color: ${SAFE_DARKER_WHITE};\n    border-style: solid;\n    border-width: 1px;\n    border-color: ${SAFE_GREY};\n    color: ${SAFE_LIGHT_BLACK};\n    line-height: 1.5;\n    padding: 0.5rem;\n    border-radius: 4px;\n    resize: vertical;\n    font-family: inherit;\n    font-size: 1rem;\n    box-sizing: border-box;\n  }\n\n  .textarea:focus {\n    outline: none;\n    border-color: ${SAFE_BLUE};\n    box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);\n  }\n`\n\nexport const SELECT = css`\n  .select {\n    position: relative;\n    width: 100%;\n    appearance: none;\n    -webkit-appearance: none !important;\n    -moz-appearance: none !important;\n    background-color: ${SAFE_DARKER_WHITE};\n    background-position: 100% center;\n    background-repeat: no-repeat;\n    border-style: solid;\n    border-width: 1px;\n    border-color: ${SAFE_GREY};\n    color: ${SAFE_LIGHT_BLACK};\n    line-height: normal;\n    padding: 0.25rem 0.5rem;\n    border-radius: 1rem;\n    cursor: pointer;\n  }\n\n  .select.chocolate {\n    background-color: ${SAFE_CHOCOLATE};\n    color: white;\n    font-weight: bold;\n    padding-right: 2rem;\n  }\n`\n\nexport const INPUT = css`\n  .input,\n  .input-number {\n    width: 100%;\n    background-color: ${SAFE_DARKER_WHITE};\n    border-style: solid;\n    border-width: 1px;\n    border-color: ${SAFE_GREY};\n    color: ${SAFE_LIGHT_BLACK};\n    line-height: normal;\n    padding: 0.25rem 0.5rem;\n    border-radius: 5px;\n    appearance: none;\n    -webkit-appearance: none !important;\n    box-sizing: border-box;\n  }\n  .input.cappucino {\n    background-color: ${SAFE_CAPPUCINO};\n    color: black;\n  }\n\n  .input {\n    -moz-appearance: none !important;\n  }\n\n  .input-number::-webkit-outer-spin-button,\n  .input-number::-webkit-inner-spin-button {\n    /* display: none; <- Crashes Chrome on hover */\n    -webkit-appearance: none;\n    margin: 0; /* <-- Apparently some margin are still there even though it's hidden */\n  }\n\n  .input-number {\n    padding: 0.25rem 0.5rem;\n    -moz-appearance: textfield !important;\n  }\n\n  .input:disabled,\n  .input-number:disabled {\n    background-color: ${SAFE_GREY};\n    color: ${SAFE_LIGHT_BLACK};\n    cursor: not-allowed;\n  }\n`\n\nexport const CHECKBOX = css`\n  .checkbox {\n    display: flex;\n    align-items: center;\n    gap: 0.4rem;\n  }\n\n  .checkbox input[type=\"checkbox\"] {\n    width: 1.2rem;\n    height: 1.2rem;\n    border: 1px solid ${SAFE_GREY};\n    border-radius: 4px;\n    margin-left: 0;\n    margin-right: 0;\n    appearance: none;\n    -webkit-appearance: none;\n    cursor: pointer;\n    position: relative;\n  }\n\n  .checkbox input[type=\"checkbox\"]:checked {\n    background-color: ${SAFE_BLUE};\n    border-color: ${SAFE_BLUE};\n  }\n\n  .checkbox input[type=\"checkbox\"]:checked::after {\n    content: \"✓\";\n    position: absolute;\n    color: white;\n    font-size: 0.8rem;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n  }\n\n  .checkbox input[type=\"checkbox\"]:focus {\n    outline: none;\n    box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);\n  }\n`\n","import { css } from \"lit\"\nimport { SAFE_GREEN, SAFE_LIGHT_GREEN } from \"../utils/colors\"\n\nexport const ALERT = css`\n  .alert {\n    padding: 8px;\n  }\n  button.alert {\n    display: flex;\n    appearance: none;\n    cursor: pointer;\n    width: 100%;\n  }\n  .error {\n    padding: 1rem;\n    text-align: center;\n    color: #d9534f;\n    background-color: #f8d7da;\n    border: 1px solid #f5c6cb;\n    border-radius: 4px;\n    margin: 0.5rem 0;\n  }\n\n  .info {\n    padding: 1rem;\n    text-align: center;\n    color: #31708f;\n    background-color: #d9edf7;\n    border: 1px solid #bce8f1;\n    border-radius: 4px;\n    margin: 0.5rem 0;\n  }\n  .warning {\n    padding: 0.75rem;\n    color: #8a6d3b;\n    background-color: #fcf8e3;\n    border: 1px solid #faebcc;\n    border-radius: 4px;\n    font-size: 0.9rem;\n    margin: 0.5rem 0;\n  }\n  .success {\n    padding: 1rem;\n    text-align: center;\n    color: ${SAFE_GREEN};\n    background-color: ${SAFE_LIGHT_GREEN};\n    border: 1px solid #d6e9c6;\n    border-radius: 4px;\n    margin: 0.5rem 0;\n    font-weight: bold;\n  }\n\n  .alert.with-icons {\n    display: grid;\n    grid-template-columns: 2rem 1fr 2rem;\n    align-items: center;\n    gap: 0.5rem;\n  }\n`\n","import { css, html, LitElement, nothing, type TemplateResult } from \"lit\"\nimport { state } from \"lit/decorators.js\"\nimport type { Constructor } from \".\"\nimport { ALERT } from \"../styles/alert\"\n\nexport declare class MessageDisplayMixinInterface {\n  messageToDisplay?: {\n    message: string\n    type: \"success\" | \"error\" | \"info\"\n  }\n\n  resetMessage(): void\n  setErrorMessage(message: string): void\n  setSuccessMessage(message: string): void\n  setInfoMessage(message: string): void\n  renderMessage(): typeof nothing | TemplateResult\n}\n\nexport const MessageDisplayMixin = <T extends Constructor<LitElement>>(\n  superClass: T\n): Constructor<MessageDisplayMixinInterface> & T => {\n  class MessageDisplayMixinClass extends superClass {\n    static styles = [\n      (superClass as unknown as typeof LitElement).styles ?? [],\n      ALERT,\n      css`\n        .alert {\n          margin-top: 1rem;\n          margin-bottom: 1rem;\n          font-weight: 700;\n        }\n      `,\n    ]\n\n    @state()\n    messageToDisplay?: {\n      message: string\n      type: \"success\" | \"error\" | \"info\"\n    }\n\n    resetMessage() {\n      this.messageToDisplay = undefined\n    }\n\n    setErrorMessage(message: string) {\n      this.messageToDisplay = {\n        message,\n        type: \"error\",\n      }\n    }\n\n    setSuccessMessage(message: string) {\n      this.messageToDisplay = {\n        message,\n        type: \"success\",\n      }\n    }\n\n    setInfoMessage(message: string) {\n      this.messageToDisplay = {\n        message,\n        type: \"info\",\n      }\n    }\n\n    renderMessage(): typeof nothing | TemplateResult {\n      return this.messageToDisplay?.message\n        ? html`<div class=\"alert ${this.messageToDisplay.type}\">\n            ${this.messageToDisplay.message}\n          </div>`\n        : nothing\n    }\n  }\n  return MessageDisplayMixinClass as unknown as Constructor<MessageDisplayMixinInterface> & T\n}\n","import { css, html, LitElement, nothing } from \"lit\"\nimport { styleMap } from \"lit/directives/style-map.js\"\nimport { customElement, property, query, state } from \"lit/decorators.js\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\nimport \"../icons/rotate-left\"\nimport \"../icons/rotate-right\"\nimport { localized, msg } from \"@lit/localize\"\nimport { mobileAndTabletCheck } from \"../../utils/breakpoints\"\n\nimport CropperCanvas from \"@cropper/element-canvas\"\nimport CropperImage from \"@cropper/element-image\"\nimport CropperHandle from \"@cropper/element-handle\"\nimport CropperSelection from \"@cropper/element-selection\"\nimport CropperCrosshair from \"@cropper/element-crosshair\"\nimport CropperShade from \"@cropper/element-shade\"\nimport type { Selection } from \"@cropper/element-selection\"\nimport { FLEX } from \"../../styles/utils\"\nimport type { CropperImageBoundingBox } from \"../../types\"\nimport { EventType } from \"../../constants\"\nimport \"../icons/arrows-center\"\nimport type { CropperActionEvent } from \"../../types/crops\"\nimport { CHECKBOX } from \"../../styles/form\"\nimport { normalizeRotation } from \"../../utils\"\nimport { MessageDisplayMixin } from \"../../mixins/message-display-mixin\"\n\nexport enum CropMode {\n  // no crop, just display image\n  IMAGE_ONLY = \"image-only\",\n  // show crop\n  CROP_READ = \"crop-read\",\n  // redefining the crop\n  CROP = \"crop\",\n}\n\nconst MessageDisplayMixinElement = MessageDisplayMixin(LitElement)\n\n/**\n * A simple zoomable image component.\n * It allows to display an image that can be zoomed, and rotated, cropped.\n * It uses the cropperjs library.\n * @element zoomable-image\n **/\n@customElement(\"zoomable-image\")\n@localized()\nexport class ZoomableImage extends MessageDisplayMixinElement {\n  static override styles = [\n    MessageDisplayMixinElement.styles || [],\n    FLEX,\n    getButtonClasses([ButtonType.White, ButtonType.Chocolate, ButtonType.LINK]),\n    CHECKBOX,\n    css`\n      :host {\n        display: block;\n        width: 100%;\n      }\n      .zoomable-image {\n        margin: 0 auto;\n      }\n      .cropper-parent {\n        position: relative;\n        overflow: hidden;\n        border: 1px solid black;\n        background-color: white;\n      }\n\n      .button-container {\n        display: flex;\n        justify-content: end;\n        gap: 0.5rem;\n        margin-top: 0.5rem;\n      }\n      .crop-result-title {\n        font-weight: bold;\n        text-align: center;\n        margin-top: 1rem;\n        margin-bottom: 0.5rem;\n      }\n      .crop-result-buttons {\n        margin-top: 0.5rem;\n      }\n\n      .toolbar .checkbox {\n        margin-right: auto;\n      }\n\n      .toolbar .checkbox span {\n        padding-top: 2px;\n      }\n\n      @media (prefers-color-scheme: dark) {\n        .link-button {\n          filter: invert(1);\n        }\n      }\n    `,\n  ]\n\n  @query(\"cropper-canvas\")\n  canvasElement!: CropperCanvas\n\n  @query(\"cropper-image\")\n  imageElement!: CropperImage\n\n  @query(\"cropper-selection\")\n  selectionElement!: CropperSelection\n\n  /*\n   * cropperjs instance\n   */\n  @state()\n  image!: HTMLImageElement\n\n  /*\n   * Image source url\n   */\n  @property({ type: String, attribute: \"src\", reflect: true })\n  src = \"\"\n\n  @property({ type: Object, attribute: \"bounding-box\", reflect: true })\n  boundingBox?: CropperImageBoundingBox = {\n    x: 0,\n    y: 0,\n    width: 100,\n    height: 100,\n  }\n\n  /**\n   * Fallback image source url\n   * If the image fails to load, this image will be displayed instead\n   */\n  @property({ type: String, attribute: \"fallback-src\", reflect: true })\n  fallbackSrc = \"\"\n\n  @state()\n  currentZoom = 1\n\n  @property({ type: Number, attribute: \"scale-size\" })\n  scaleStep = 0.25\n\n  @property({ type: Number, attribute: \"max-zoom\" })\n  maxZoom = 10\n\n  @property({ type: Number, attribute: \"min-zoom\" })\n  minZoom = 0.3\n\n  @property({ type: Boolean, attribute: \"show-buttons\", reflect: true })\n  showButtons = false\n\n  /**\n   * The crop mode for the image\n   */\n  @property({ type: String, attribute: \"crop-mode\", reflect: true })\n  cropMode: CropMode = CropMode.IMAGE_ONLY\n\n  @property({ type: Object, attribute: \"size\", reflect: true })\n  size: {\n    width: string\n    height?: string\n    \"max-width\"?: string\n    \"max-height\"?: string\n  } = {\n    width: \"100%\",\n    height: \"30vh\",\n  }\n\n  // original rotation of the image\n  @property({ type: Number, reflect: true })\n  get rotation() {\n    return this._rotation ?? 0\n  }\n  set rotation(value) {\n    this._rotation = value\n    this.resetRotatation()\n  }\n\n  @state()\n  private _rotation = 0\n\n  @state()\n  private currentRotation = 0\n\n  @state()\n  private cropResult: string = \"\"\n\n  @state()\n  private resultBoundingBox?: CropperImageBoundingBox\n\n  @state()\n  private isCanvasEnabledInMobile = false\n\n  get isMobileOrTablet() {\n    return mobileAndTabletCheck()\n  }\n\n  get isCanvasDisabled() {\n    return this.isMobileOrTablet && !this.isCanvasEnabledInMobile\n  }\n  /**\n   * The last transform applied to the image.\n   * Used to reset the image to its original position.\n   */\n  @state()\n  lastTransform: number[] = []\n\n  get canZoom() {\n    return !mobileAndTabletCheck()\n  }\n\n  /**\n   * Called when an attribute is changed.\n   * Allows to fit the image to the container when the src attribute is changed.\n   */\n  override attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n    super.attributeChangedCallback(name, _old, value)\n\n    switch (name) {\n      case \"src\":\n        this.resetRotatation()\n        break\n      case \"size\":\n        this.fitImageToContainer()\n        break\n      case \"crop-mode\":\n        this.resetMessage()\n        break\n    }\n  }\n\n  /**\n   * Called after the component is first updated.\n   * Used to initialize the cropper.\n   */\n  override firstUpdated() {\n    this.initCropper()\n  }\n\n  /**\n   * Called when the component is disconnected from the DOM.\n   * Used to remove the event listener from the cropper canvas.\n   */\n  override disconnectedCallback(): void {\n    this.canvasElement.removeEventListener(\"actionstart\", (e) => {\n      this.onCropperCanvasAction(e as CropperActionEvent)\n    })\n    super.disconnectedCallback()\n  }\n\n  /**\n   * Initializes the zoom limit for the cropper canvas.\n   * This is used to prevent the user from zooming in or out too much.\n   */\n  initZoomLimit() {\n    this.canvasElement.addEventListener(\"action\", (e) => {\n      this.onCropperCanvasAction(e as CropperActionEvent)\n    })\n  }\n\n  resetRotatation() {\n    this.currentRotation = 0\n    this.imageElement?.$resetTransform()\n    this.rotateImage(this.rotation)\n  }\n\n  /**\n   * Initializes the cropper components, as required by cropperjs.\n   * (add them to the CustomElementRegistry)\n   */\n  initCropper() {\n    CropperCanvas.$define()\n    CropperImage.$define()\n    CropperHandle.$define()\n\n    CropperSelection.$define()\n    CropperCrosshair.$define()\n    CropperShade.$define()\n\n    this.initZoomLimit()\n    // Reset the rotation when the image is ready to be displayed\n    this.imageElement.$ready(() => {\n      this.resetRotatation()\n    })\n  }\n\n  /**\n   * Updates the last transform of the image.\n   * This is used to rollback the image if user zooms out too much.\n   */\n  updateLastTransform() {\n    this.lastTransform = this.imageElement?.$getTransform()\n  }\n\n  /**\n   * Centers the image and fits it within its container.\n   * This ensures the image is properly scaled and positioned to be fully visible.\n   */\n  fitImageToContainer() {\n    if (!this.imageElement && this.src) {\n      return\n    }\n\n    // Use requestAnimationFrame instead of setTimeout for better performance\n    requestAnimationFrame(() => {\n      try {\n        this.imageElement.$center(\"contain\")\n        this.updateLastTransform()\n      } catch (error) {\n        console.error(\"Error fitting image to container:\", error)\n      }\n    })\n  }\n\n  /**\n   * Rotates the image by the specified angle with error handling.\n   * @param rotation - The angle to rotate the image by.\n   */\n  rotateImage(rotation: number) {\n    if (!this.imageElement) return\n    try {\n      // Reset the selection before rotating the image\n      this.resetSelection()\n\n      if (!this.imageElement.rotatable) {\n        // Enable rotation if it's not already enabled (bug fix)\n        this.imageElement.rotatable = true\n      }\n\n      this.imageElement.$rotate(`${rotation}deg`)\n      // Update the rotation property\n      this.currentRotation = normalizeRotation(this.currentRotation + rotation)\n\n      this.dispatchEvent(new CustomEvent(\"rotate\", { detail: { rotation: this.currentRotation } }))\n\n      this.fitImageToContainer()\n    } catch (error) {\n      console.error(\"Error rotating image:\", error)\n    }\n  }\n  /**\n   * Renders the center button with accessibility attributes.\n   * @returns The rendered center button.\n   */\n  renderCenterButton() {\n    return html`\n      <button\n        class=\"link-button\"\n        @click=${this.fitImageToContainer}\n        title=${msg(\"Center image\")}\n        aria-label=${msg(\"Center image\")}\n      >\n        <arrows-center-icon size=\"20px\" aria-hidden=\"true\"></arrows-center-icon>\n      </button>\n    `\n  }\n\n  /**\n   * Renders the rotate buttons with accessibility attributes.\n   * @returns The rendered rotate buttons.\n   */\n  renderRotateButtons() {\n    return html`\n      <button\n        class=\"link-button\"\n        @click=${() => this.rotateImage(-90)}\n        title=${msg(\"Rotate image to the left\")}\n        aria-label=${msg(\"Rotate image to the left\")}\n      >\n        <rotate-left-icon aria-hidden=\"true\"></rotate-left-icon>\n      </button>\n      <button\n        class=\"link-button\"\n        @click=${() => this.rotateImage(90)}\n        title=${msg(\"Rotate image to the right\")}\n        aria-label=${msg(\"Rotate image to the right\")}\n      >\n        <rotate-right-icon aria-hidden=\"true\"></rotate-right-icon>\n      </button>\n    `\n  }\n\n  /**\n   * Transforms coordinates to account for image rotation.\n   * @param x - The x coordinate of the selection\n   * @param y - The y coordinate of the selection\n   * @param width - The width of the selection\n   * @param height - The height of the selection\n   * @param imageWidth - The image width (considering rotation)\n   * @param imageHeight - The image height (considering rotation)\n   * @param rotation - The rotation angle in degrees\n   * @returns The transformed coordinates\n   */\n  transformCoordsForRotation(\n    x: number,\n    y: number,\n    width: number,\n    height: number,\n    imageWidth: number,\n    imageHeight: number,\n    rotation: number\n  ) {\n    // Normalize rotation to 0, 90, 180, or 270 degrees\n    const normalizedRotation = ((rotation % 360) + 360) % 360\n\n    switch (normalizedRotation) {\n      case 90:\n        // 90° clockwise rotation: (x,y) -> (y, imageWidth-x-width)\n        return {\n          x: y,\n          y: imageWidth - x - width,\n          width: height,\n          height: width,\n        }\n      case 180:\n        // 180° rotation: (x,y) -> (imageWidth-x-width, imageHeight-y-height)\n        return {\n          x: imageWidth - x - width,\n          y: imageHeight - y - height,\n          width: width,\n          height: height,\n        }\n      case 270:\n        // 270° clockwise rotation: (x,y) -> (imageHeight-y-height, x)\n        return {\n          x: imageHeight - y - height,\n          y: x,\n          width: height,\n          height: width,\n        }\n      default:\n        // No rotation or 0°\n        return { x, y, width, height }\n    }\n  }\n\n  /**\n   * Gets the bounding box from the selection element.\n   * @returns The bounding box coordinates.\n   */\n  getBoundingBoxFromSelectionElement() {\n    const { x: offsetX, y: offsetY } = this.getOffset()\n    const scale = this.getScale()\n\n    // Get the selection coordinates relative to the image\n    let x = (this.selectionElement.x - offsetX) / scale\n    let y = (this.selectionElement.y - offsetY) / scale\n    let width = this.selectionElement.width / scale\n    let height = this.selectionElement.height / scale\n\n    // Handle rotation if the image is rotated\n    if (this.currentRotation !== 0) {\n      const image = this.imageElement?.$image\n      if (image) {\n        const imageWidth = image.naturalWidth\n        const imageHeight = image.naturalHeight\n\n        // For 90° and 270° rotations, we need to adjust the coordinates\n        // because the image dimensions are swapped in the display\n        const normalizedRotation = ((this.currentRotation % 360) + 360) % 360\n\n        if (normalizedRotation === 90 || normalizedRotation === 270) {\n          // When rotated 90° or 270°, the displayed image has swapped dimensions\n          // We need to account for this when calculating the relative coordinates\n          const displayedImageWidth = imageHeight\n          const displayedImageHeight = imageWidth\n\n          // Transform coordinates based on rotation using the correct dimensions\n          const rotatedCoords = this.transformCoordsForRotation(\n            x,\n            y,\n            width,\n            height,\n            displayedImageWidth,\n            displayedImageHeight,\n            this.currentRotation\n          )\n\n          x = rotatedCoords.x\n          y = rotatedCoords.y\n          width = rotatedCoords.width\n          height = rotatedCoords.height\n        } else {\n          // 180° rotations, use original dimensions\n          const rotatedCoords = this.transformCoordsForRotation(\n            x,\n            y,\n            width,\n            height,\n            imageWidth,\n            imageHeight,\n            this.currentRotation\n          )\n\n          x = rotatedCoords.x\n          y = rotatedCoords.y\n          width = rotatedCoords.width\n          height = rotatedCoords.height\n        }\n      }\n    }\n\n    return { x, y, width, height }\n  }\n\n  /**\n   * Shows the cropped image.\n   */\n  async showCrop() {\n    this.resetMessage()\n    if (!this.hasSelection()) {\n      this.setErrorMessage(msg(\"Please select a region to crop.\"))\n      return\n    }\n    this.resultBoundingBox = this.getBoundingBoxFromSelectionElement()\n\n    const result = await this.selectionElement.$toCanvas()\n    this.cropResult = result.toDataURL()\n  }\n\n  /**\n   * Resets the selection.\n   */\n  resetSelection() {\n    this.resetMessage()\n    this.selectionElement?.$clear()\n  }\n\n  /**\n   * Resets the crop.\n   */\n  resetCrop() {\n    this.cropResult = \"\"\n    this.resultBoundingBox = undefined\n    this.resetSelection()\n  }\n\n  /**\n   * Submits the crop.\n   */\n  submitCrop() {\n    this.dispatchEvent(\n      new CustomEvent(EventType.SUBMIT, {\n        detail: {\n          newBoundingBox: this.resultBoundingBox,\n          oldBoundingBox: this.boundingBox,\n          rotation: this.currentRotation,\n        },\n      })\n    )\n    this.resetCrop()\n  }\n\n  /**\n   * Renders the crop mode UI with accessibility attributes.\n   * @returns The crop mode UI.\n   */\n  renderCropMode() {\n    return html`\n      <div>\n        ${this.renderMessage()}\n        <div class=\"button-container\">\n          <button\n            class=\"button white-button small\"\n            @click=${this.resetCrop}\n            aria-label=${msg(\"Reset selection\")}\n          >\n            ${msg(\"Reset selection\")}\n          </button>\n          <button\n            class=\"button chocolate-button small\"\n            @click=${this.showCrop}\n            aria-label=${msg(\"Show crop\")}\n          >\n            ${msg(\"Show crop\")}\n          </button>\n        </div>\n\n        ${this.renderCropImageBoundingBox()}\n      </div>\n    `\n  }\n\n  /**\n   * Renders the crop image bounding box with accessibility attributes.\n   * @returns The crop image bounding box UI.\n   */\n  renderCropImageBoundingBox() {\n    if (!this.cropResult) {\n      return nothing\n    }\n    return html`\n      <div>\n        <div class=\"crop-result-title\">${msg(\"Crop Result\")}</div>\n        <div class=\"flex justify-center\">\n          <img src=${this.cropResult} alt=${msg(\"Cropped Image\")} />\n        </div>\n        <div class=\"crop-result-buttons flex justify-center gap-0_5\">\n          <button\n            class=\"button chocolate-button\"\n            @click=${this.submitCrop}\n            aria-label=${msg(\"Validate crop\")}\n          >\n            ${msg(\"Validate crop\")}\n          </button>\n          <button\n            class=\"button white-button\"\n            @click=${this.resetCrop}\n            aria-label=${msg(\"Reset crop\")}\n          >\n            ${msg(\"Reset crop\")}\n          </button>\n        </div>\n      </div>\n    `\n  }\n\n  /**\n   * Gets the offset of the cropper image relative to the canvas.\n   * @returns The offset coordinates.\n   */\n  getOffset() {\n    const cropperImageRect = this.imageElement.getBoundingClientRect()\n    const cropperCanvasRect = this.canvasElement.getBoundingClientRect()\n    return {\n      x: cropperImageRect.left - cropperCanvasRect.left,\n      y: cropperImageRect.top - cropperCanvasRect.top,\n    }\n  }\n\n  /**\n   * Gets the scale of the cropper image.\n   * @returns The scale coordinates.\n   */\n  getScale() {\n    const transformValue = this.imageElement.$getTransform()\n\n    const index = (this.currentRotation / 90) % 2\n    return Math.abs(transformValue[index])\n  }\n  /**\n   * Calculates the scale of the image relative to the canvas size using current image width.\n   * @returns The scale factor as a number.\n   */\n  getImageScaleRelativeToCanvas(): number {\n    if (!this.imageElement || !this.canvasElement) {\n      return 1\n    }\n\n    const image = this.imageElement.$image\n    const canvas = this.canvasElement\n\n    if (!image || !canvas) {\n      return 1\n    }\n\n    // Get the current width and height of the image as displayed in the canvas\n    const imageRect = this.imageElement.getBoundingClientRect()\n    const imageWidth = imageRect.width\n    const imageHeight = imageRect.height\n    const canvasWidth = canvas.clientWidth\n    const canvasHeight = canvas.clientHeight\n\n    // Calculate the scale factor based on width and height\n    const widthScale = imageWidth / canvasWidth\n    const heightScale = imageHeight / canvasHeight\n\n    // Return the larger scale factor to ensure the image fits within the canvas\n    return Math.max(widthScale, heightScale)\n  }\n\n  /**\n   * Gets the bounding box depending on the image size.\n   * @returns The bounding box coordinates.\n   */\n  getBoundingBoxDependOnImageSize() {\n    const image = this.imageElement?.$image\n    if (!this.boundingBox) {\n      console.error(\"No bounding box\")\n    }\n    if (!image) {\n      return this.boundingBox\n    }\n    const { x: offsetX, y: offsetY } = this.getOffset()\n    const scale = this.getScale()\n\n    let boundingBox = { ...this.boundingBox! }\n\n    // Handle rotation - transform the bounding box coordinates\n    if (this.currentRotation !== 0) {\n      const imageWidth = image.naturalWidth\n      const imageHeight = image.naturalHeight\n\n      // Apply inverse rotation to get the correct position for the rotated image\n      const inverseRotation = (360 - this.currentRotation) % 360\n      const rotatedCoords = this.transformCoordsForRotation(\n        boundingBox.x,\n        boundingBox.y,\n        boundingBox.width,\n        boundingBox.height,\n        imageWidth,\n        imageHeight,\n        inverseRotation\n      )\n\n      boundingBox = rotatedCoords\n    }\n\n    return {\n      x: boundingBox.x * scale + offsetX,\n      y: boundingBox.y * scale + offsetY,\n      width: boundingBox.width * scale,\n      height: boundingBox.height * scale,\n    }\n  }\n\n  /**\n   * Renders the cropper controls with proper accessibility attributes.\n   * @returns The cropper controls UI.\n   */\n  renderCropperControls() {\n    if (this.cropMode === CropMode.IMAGE_ONLY) {\n      return html`\n        <cropper-handle action=\"move\" plain aria-label=${msg(\"Move image\")}></cropper-handle>\n      `\n    } else if (this.cropMode === CropMode.CROP_READ) {\n      const boundingBox = this.getBoundingBoxDependOnImageSize()\n      return html`\n        <cropper-shade aria-hidden=\"true\"></cropper-shade>\n        <cropper-handle action=\"move\" plain aria-label=${msg(\"Move image\")}></cropper-handle>\n        <cropper-selection\n          outlined\n          @change=\"${this.onCropperSelectionChange}\"\n          x=${boundingBox?.x ?? 0}\n          y=${boundingBox?.y ?? 0}\n          width=${boundingBox?.width ?? 0}\n          height=${boundingBox?.height ?? 0}\n          dynamic\n          movable\n          resizable\n          aria-label=${msg(\"Selection area\")}\n        >\n          <cropper-handle action=\"move\" plain aria-label=${msg(\"Move selection\")}></cropper-handle>\n        </cropper-selection>\n      `\n    }\n\n    return html`\n      <cropper-shade hidden aria-hidden=\"true\"></cropper-shade>\n      <cropper-handle action=\"select\" plain aria-label=${msg(\"Select area\")}></cropper-handle>\n      <cropper-selection\n        dynamic\n        movable\n        resizable\n        hidden\n        zoomable\n        @change=\"${this.onCropperSelectionChange}\"\n        aria-label=${msg(\"Selection area\")}\n      >\n        <cropper-handle action=\"move\" plain aria-label=${msg(\"Move selection\")}></cropper-handle>\n        <cropper-handle action=\"n-resize\" aria-label=${msg(\"Resize top\")}></cropper-handle>\n        <cropper-handle action=\"e-resize\" aria-label=${msg(\"Resize right\")}></cropper-handle>\n        <cropper-handle action=\"s-resize\" aria-label=${msg(\"Resize bottom\")}></cropper-handle>\n        <cropper-handle action=\"w-resize\" aria-label=${msg(\"Resize left\")}></cropper-handle>\n        <cropper-handle action=\"ne-resize\" aria-label=${msg(\"Resize top right\")}></cropper-handle>\n        <cropper-handle action=\"nw-resize\" aria-label=${msg(\"Resize top left\")}></cropper-handle>\n        <cropper-handle\n          action=\"se-resize\"\n          aria-label=${msg(\"Resize bottom right\")}\n        ></cropper-handle>\n        <cropper-handle action=\"sw-resize\" aria-label=${msg(\"Resize bottom left\")}></cropper-handle>\n      </cropper-selection>\n    `\n  }\n\n  /**\n   * Checks if the selection is within the maximum selection.\n   * @param selection - The selection to check.\n   * @param maxSelection - The maximum selection.\n   * @returns True if the selection is within the maximum selection, false otherwise.\n   */\n  inSelection(selection: Selection, maxSelection: Selection) {\n    return (\n      selection.x >= maxSelection.x &&\n      selection.y >= maxSelection.y &&\n      selection.x + selection.width <= maxSelection.x + maxSelection.width &&\n      selection.y + selection.height <= maxSelection.y + maxSelection.height\n    )\n  }\n\n  /**\n   * Checks if there is a selection.\n   * @returns True if there is a selection, false otherwise.\n   */\n  hasSelection() {\n    const isSelectionHidden = this.selectionElement?.hidden ?? true\n    const hasNoSize = this.selectionElement?.width === 0 || this.selectionElement?.height === 0\n    return !isSelectionHidden && !hasNoSize\n  }\n\n  /**\n   * Handles the cropper image transform event.\n   * @param event - The transform event.\n   */\n  onCropperImageTransform(event: CustomEvent<{ matrix: number[] }>) {\n    // If the crop mode is not CROP and you have a selection, you need to update the selection.\n    if (this.cropMode !== CropMode.CROP) {\n      return\n    }\n\n    const cropperCanvas = this.canvasElement\n\n    if (!cropperCanvas || !this.hasSelection()) {\n      return\n    }\n\n    const cropperSelection = this.selectionElement\n    const cropperCanvasRect = cropperCanvas.getBoundingClientRect()\n\n    // 1. Clone the cropper image.\n    const cropperImageClone = this.imageElement.cloneNode() as CropperImage\n\n    // 2. Apply the new matrix to the cropper image clone.\n    cropperImageClone.style.transform = `matrix(${event.detail.matrix.join(\", \")})`\n\n    // 3. Make the cropper image clone invisible.\n    cropperImageClone.style.opacity = \"0\"\n\n    // 4. Append the cropper image clone to the cropper canvas.\n    cropperCanvas.appendChild(cropperImageClone)\n\n    // 5. Compute the boundaries of the cropper image clone.\n    const cropperImageRect = cropperImageClone.getBoundingClientRect()\n\n    // 6. Remove the cropper image clone.\n    cropperCanvas.removeChild(cropperImageClone)\n\n    const selection = cropperSelection as Selection\n    const maxSelection: Selection = {\n      x: cropperImageRect.left - cropperCanvasRect.left,\n      y: cropperImageRect.top - cropperCanvasRect.top,\n      width: cropperImageRect.width,\n      height: cropperImageRect.height,\n    }\n\n    if (!this.inSelection(selection, maxSelection)) {\n      event.preventDefault()\n    }\n  }\n\n  /**\n   * Handles the cropper selection change event.\n   * @param event - The selection change event.\n   */\n  onCropperSelectionChange(event: CustomEvent) {\n    if (this.cropMode !== CropMode.CROP) {\n      return\n    }\n    const cropperCanvas = this.canvasElement\n\n    if (!cropperCanvas) {\n      return\n    }\n\n    const cropperCanvasRect = cropperCanvas.getBoundingClientRect()\n    const selection = event.detail as Selection\n\n    const cropperImage = this.imageElement\n    const cropperImageRect = cropperImage.getBoundingClientRect()\n    const maxSelection: Selection = {\n      x: cropperImageRect.left - cropperCanvasRect.left,\n      y: cropperImageRect.top - cropperCanvasRect.top,\n      width: cropperImageRect.width,\n      height: cropperImageRect.height,\n    }\n\n    if (!this.inSelection(selection, maxSelection)) {\n      event.preventDefault()\n    }\n  }\n\n  /**\n   * Renders the mobile canvas toggle checkbox.\n   * @returns The mobile canvas toggle UI.\n   */\n  renderMobileCanvasToggle() {\n    if (!this.isMobileOrTablet) {\n      return nothing\n    }\n\n    return html`\n      <label class=\"checkbox\">\n        <input\n          type=\"checkbox\"\n          .checked=${this.isCanvasEnabledInMobile}\n          @change=${(e: Event) => {\n            this.isCanvasEnabledInMobile = (e.target as HTMLInputElement).checked\n          }}\n        />\n        <span> ${msg(\"Move image\")} </span>\n      </label>\n    `\n  }\n\n  /**\n   * Renders the top panel with proper accessibility attributes.\n   * @returns The top panel UI.\n   */\n  renderTopPanel() {\n    if (!this.showButtons) {\n      return nothing\n    }\n\n    return html`\n      <div class=\"toolbar flex justify-end\" role=\"toolbar\" aria-label=${msg(\"Image controls\")}>\n        ${this.renderMobileCanvasToggle()} ${this.renderCenterButton()}\n        ${this.renderRotateButtons()}\n      </div>\n    `\n  }\n\n  /**\n   * Handles zoom changes to ensure they stay within the specified bounds.\n   * @param zoom - The new zoom level.\n   * @returns True if zoom is allowed, false otherwise.\n   */\n  allowZoomChange(zoom: number): boolean {\n    return zoom <= this.maxZoom && zoom >= this.minZoom\n  }\n\n  /**\n   * Handles cropper canvas actions with error handling.\n   * @param event - The cropper canvas action event.\n   */\n  onCropperCanvasAction(event: CropperActionEvent) {\n    try {\n      const { action } = event.detail\n      if (action === \"scale\") {\n        const isAllowed = this.allowZoomChange(this.getImageScaleRelativeToCanvas())\n        if (!isAllowed) {\n          event.preventDefault()\n          // rollback the scale\n          this.imageElement.$setTransform(this.lastTransform)\n        }\n      }\n      this.updateLastTransform()\n    } catch (error) {\n      console.error(\"Error in cropper canvas action:\", error)\n    }\n  }\n\n  /**\n   * Renders the component with accessibility attributes.\n   * @returns The component UI.\n   */\n  override render() {\n    const crossorigin = this.cropMode !== CropMode.IMAGE_ONLY ? \"anonymous\" : undefined\n    return html`\n      <div\n        class=\"zoomable-image\"\n        style=${styleMap({\n          width: this.size.width,\n          \"max-width\": this.size[\"max-width\"],\n        })}\n        role=\"region\"\n        aria-label=${msg(\"Zoomable image\")}\n      >\n        ${this.renderTopPanel()}\n        <div class=\"cropper-parent\">\n          <cropper-canvas\n            background\n            style=${styleMap(this.size)}\n            scale-step=${this.scaleStep}\n            aria-label=${msg(\"Image canvas\")}\n            ?disabled=${this.isCanvasDisabled}\n          >\n            <cropper-image\n              src=${this.src}\n              alt=${msg(\"Picture\")}\n              rotable\n              scalable\n              skewable\n              translatable\n              ?crossorigin=\"${crossorigin}\"\n              @transform=${this.onCropperImageTransform}\n            ></cropper-image>\n            ${this.renderCropperControls()}\n          </cropper-canvas>\n        </div>\n        ${this.cropMode === CropMode.CROP ? html` ${this.renderCropMode()} ` : nothing}\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"zoomable-image\": ZoomableImage\n  }\n}\n","import { LitElement, html, css, nothing } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { type Question, AnnotationAnswer } from \"../../types/robotoff\"\nimport { EventType } from \"../../constants\"\nimport { answerQuestion } from \"../../signals/questions\"\nimport { SignalWatcher } from \"@lit-labs/signals\"\nimport { localized, msg } from \"@lit/localize\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\nimport { LoadingWithTimeoutMixin } from \"../../mixins/loading-with-timeout-mixin\"\nimport { FULL_WIDTH } from \"../../styles/utils\"\nimport \"../shared/loading-button\"\nimport \"../buttons/zoom-unzoom-button\"\nimport \"../shared/zoomable-image\"\n\n/**\n * RobotoffQuestionForm component\n * It displays a form to answer a question about a product.\n * @element robotoff-question-form\n * @fires {EventType.SUBMIT} - When the form is submitted\n */\n@customElement(\"robotoff-question-form\")\n@localized()\nexport class RobotoffQuestionForm extends SignalWatcher(\n  LoadingWithTimeoutMixin(LitElement, undefined as AnnotationAnswer | undefined)\n) {\n  static override styles = [\n    ...getButtonClasses([ButtonType.White]),\n    FULL_WIDTH,\n    css`\n      :host {\n        display: block;\n      }\n\n      .question-form {\n        display: flex;\n        align-items: center;\n        flex-direction: column;\n      }\n\n      .image-wrapper {\n        width: 100%;\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n        position: relative;\n      }\n\n      .img-button-wrapper {\n        position: absolute;\n        bottom: 0.5rem;\n        right: 0.5rem;\n        display: flex;\n        justify-content: center;\n      }\n      .expand-button {\n        margin-top: 1rem;\n      }\n      .buttons-row {\n        margin-top: 1rem;\n      }\n    `,\n  ]\n\n  /** The question to display. */\n  @property({ type: Object, reflect: true })\n  question?: Question\n\n  /** True if the image is expanded (and zoomable). */\n  @property({ type: Boolean, attribute: \"is-image-expanded\" })\n  isImageExpanded: boolean = false\n\n  get imageSize() {\n    return this.isImageExpanded\n      ? { height: \"350px\", width: \"100%\", \"max-width\": \"350px\" }\n      : { height: \"200px\", width: \"200px\" }\n  }\n\n  /**\n   * Emit an event submit when the user clicks on a button.\n   * It stops the propagation of the event to avoid the click event on the parent.\n   */\n  private emitEventClick = (event: Event, value: AnnotationAnswer) => {\n    event.stopPropagation()\n    const click = new CustomEvent(EventType.SUBMIT, {\n      detail: { value },\n      bubbles: true,\n      composed: true,\n    })\n\n    this.dispatchEvent(click)\n  }\n\n  private _annotateProduct = async (event: Event, value: AnnotationAnswer) => {\n    this.showLoading(value)\n    await answerQuestion(this.question?.insight_id!, value)\n\n    this.hideLoading()\n    this.emitEventClick(event, value)\n  }\n\n  expandImage() {\n    this.isImageExpanded = true\n  }\n\n  private _renderImage() {\n    if (!this.question?.source_image_url) {\n      return nothing\n    }\n\n    return html`\n      <div class=\"image-wrapper\">\n        <zoomable-image\n          src=${this.question?.source_image_url}\n          .size=${this.imageSize}\n          @click=\"${this.expandImage}\"\n          ?show-buttons=\"${this.isImageExpanded}\"\n        ></zoomable-image>\n        ${this.isImageExpanded\n          ? nothing\n          : html`<div>\n              <button class=\"expand-button button white-button small\" @click=\"${this.expandImage}\">\n                ${msg(\"Expand image\")}\n              </button>\n            </div>`}\n      </div>\n    `\n  }\n\n  private renderButtons() {\n    const isLoading = Boolean(this.loading)\n    return html`\n      <div class=\"buttons-row\">\n        <loading-button\n          css-classes=\"button success-button\"\n          .loading=${this.loading === AnnotationAnswer.ACCEPT}\n          .disabled=${isLoading}\n          @click=\"${(event: Event) => this._annotateProduct(event, AnnotationAnswer.ACCEPT)}\"\n          label=\"${msg(\"Yes\")}\"\n        ></loading-button>\n        <loading-button\n          css-classes=\"button danger-button\"\n          .loading=${this.loading === AnnotationAnswer.REFUSE}\n          .disabled=${isLoading}\n          @click=\"${(event: Event) => this._annotateProduct(event, AnnotationAnswer.REFUSE)}\"\n          label=\"${msg(\"No\")}\"\n        ></loading-button>\n        <loading-button\n          css-classes=\"button cappucino-button\"\n          .loading=${this.loading === AnnotationAnswer.SKIP}\n          .disabled=${isLoading}\n          @click=\"${(event: Event) => this._annotateProduct(event, AnnotationAnswer.SKIP)}\"\n          label=\"${msg(\"Skip\")}\"\n        ></loading-button>\n      </div>\n    `\n  }\n\n  override render() {\n    if (!this.question) {\n      return html`<div>No question</div>`\n    }\n\n    return html`\n      <div class=\"question-form\">\n        <p>${this.question.question} <strong> ${this.question.value} </strong></p>\n        <div>${this._renderImage()}</div>\n        ${this.renderButtons()}\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"robotoff-question-form\": RobotoffQuestionForm\n  }\n}\n","import { css } from \"lit\"\n\n/**\n * Base styles for all components\n * - Font family : It is necessary to import the font in the index.html file\n */\nexport const BASE = css`\n  :host {\n    font-family: var(--font-family, \"Public Sans\", Helvetica, Roboto, Arial, sans-serif);\n  }\n`\n\nexport const ICON_BASE = css`\n  :host {\n    display: inline-flex;\n  }\n`\n","import { LitElement, html, css, nothing, type TemplateResult } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport {\n  currentQuestionIndex,\n  fetchQuestionsByProductCode,\n  nextQuestionByProductCode,\n  isQuestionsFinished,\n  questions,\n  hasQuestions,\n  numberOfQuestions,\n} from \"../../signals/questions\"\nimport { Task } from \"@lit/task\"\nimport { localized, msg } from \"@lit/localize\"\nimport { EventState, EventType } from \"../../constants\"\nimport type { QuestionStateEventDetail } from \"../../types\"\nimport { SignalWatcher } from \"@lit-labs/signals\"\nimport \"../shared/loader\"\nimport \"./robotoff-question-form\"\nimport { BASE } from \"../../styles/base\"\n\n/**\n * Robotoff question component\n * @element robotoff-question\n * @fires {EventType.QUESTION_STATE} - When the state of the question changes\n */\n@customElement(\"robotoff-question\")\n@localized()\nexport class RobotoffQuestion extends SignalWatcher(LitElement) {\n  static override styles = [\n    BASE,\n    css`\n      :host {\n        display: block;\n        padding: 1rem;\n      }\n      .question-wrapper {\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n        text-align: center;\n      }\n      .message {\n        font-style: italic;\n        color: var(--robotoff-question-message-color, #444);\n      }\n      @media (prefers-color-scheme: dark) {\n        :host {\n          background: var(--robotoff-question-bg-dark, #181a1b);\n          color: var(--robotoff-question-color-dark, #f3f3f3);\n        }\n        .message {\n          color: var(--robotoff-question-message-color-dark, #b3b3b3);\n        }\n      }\n    `,\n  ]\n\n  @property({ type: Boolean, attribute: \"show-message\" })\n  showMessage = true\n\n  @property({ type: Boolean, attribute: \"show-loading\" })\n  showLoading = true\n\n  @property({ type: Boolean, attribute: \"show-error\" })\n  showError = true\n\n  @property({ type: Boolean, attribute: \"image-expanded\" })\n  isImageExpanded = false\n\n  /** Product code to fetch questions for */\n  @property({ type: String, attribute: \"product-code\" })\n  productCode: string = \"\"\n\n  /** Insight types to filter questions, comma-separated */\n  @property({ type: String, attribute: \"insight-types\" })\n  insightTypes: string = \"\"\n\n  /** Whether the user has answered the question */\n  @state()\n  private hasAnswered: boolean = false\n\n  /** Task to fetch questions for the given product code */\n  private _questionsTask = new Task(this, {\n    task: async ([productCode, insightTypes]) => {\n      this.hasAnswered = false\n      if (!productCode) return []\n      const params = insightTypes ? { insight_types: insightTypes } : {}\n      this._emitQuestionStateEvent(EventState.LOADING)\n      await fetchQuestionsByProductCode(productCode, params)\n      const value = questions(productCode).get()\n      this._emitQuestionStateEvent(value?.length > 0 ? EventState.HAS_DATA : EventState.NO_DATA)\n      return value\n    },\n    args: () => [this.productCode, this.insightTypes],\n  })\n\n  /** Emit a custom event when the question state changes */\n  private _emitQuestionStateEvent(state: EventState): void {\n    const detail: QuestionStateEventDetail =\n      state === EventState.LOADING\n        ? { state }\n        : {\n            state,\n            index: currentQuestionIndex(this.productCode).get(),\n            numberOfQuestions: numberOfQuestions(this.productCode).get(),\n          }\n    this.dispatchEvent(\n      new CustomEvent(EventType.QUESTION_STATE, {\n        detail,\n        bubbles: true,\n        composed: true,\n      })\n    )\n  }\n\n  private onQuestionAnswered = (): void => {\n    this.hasAnswered = true\n    nextQuestionByProductCode(this.productCode)\n    this.requestUpdate()\n    this._emitQuestionStateEvent(EventState.ANNOTATED)\n    if (isQuestionsFinished(this.productCode).get()) {\n      this._emitQuestionStateEvent(EventState.FINISHED)\n    }\n  }\n\n  /** Render the message to display to the user */\n  private renderMessage(): TemplateResult | typeof nothing {\n    const getMessageWrapper = (message: string) => html`<div class=\"message\">${message}</div>`\n    if (isQuestionsFinished(this.productCode).get()) {\n      return getMessageWrapper(msg(\"Thank you for your assistance!\"))\n    }\n    if (!this.showMessage) {\n      return nothing\n    }\n    if (!this.hasAnswered) {\n      return getMessageWrapper(msg(\"Open Food Facts needs your help with this product.\"))\n    }\n    return html`<div>${msg(\"Thanks for your help! Can you assist with another question?\")}</div>`\n  }\n\n  override render() {\n    return this._questionsTask.render({\n      pending: () => (this.showLoading ? html`<off-wc-loader></off-wc-loader>` : nothing),\n      error: (error) => (this.showError ? html`<div>Error: ${error}</div>` : nothing),\n      complete: (questionsList) => {\n        const index = currentQuestionIndex(this.productCode).get() ?? 0\n        const question = questionsList[index]\n        if (!hasQuestions(this.productCode).get()) {\n          return html`<slot></slot>`\n        }\n        return html`\n          <div class=\"question-wrapper\">\n            ${this.renderMessage()}\n            ${isQuestionsFinished(this.productCode).get()\n              ? nothing\n              : html`\n                  <robotoff-question-form\n                    .isImageExpanded=${this.isImageExpanded}\n                    .question=${question}\n                    @submit=${this.onQuestionAnswered}\n                  ></robotoff-question-form>\n                `}\n          </div>\n        `\n      },\n    })\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"robotoff-question\": RobotoffQuestion\n  }\n}\n","import { Computed } from \"@lit-labs/signals\"\nimport robotoff from \"../api/robotoff\"\nimport {\n  type NutrientsInsight,\n  type InsightAnnotationAnswer,\n  type InsightsRequestParams,\n  type NutrientsAnnotationData,\n  InsightType,\n  AnnotationAnswer,\n} from \"../types/robotoff\"\nimport { SignalMap } from \"../utils/signals\"\n\n/**\n * Nutrients insights by insight id\n */\nexport const insightById = new SignalMap<NutrientsInsight>({})\n\n/**\n * Nutrients insights id by product code\n */\nexport const insightIdByProductCode = new SignalMap<string | null>({})\n\n/**\n * Get the insight for a given product code\n * @param productCode\n * @returns {Computed<NutrientsInsight | undefined>}\n */\nexport const insight = (productCode: string) => {\n  return new Computed<NutrientsInsight | undefined>(() => {\n    const insightId = insightIdByProductCode.getItem(productCode)\n    if (!insightId) {\n      return undefined\n    }\n    return insightById.getItem(insightId)\n  })\n}\n\n/**\n * Fetch the incomplete nutrients insights for a given product code\n * @param productCode\n */\nexport const fetchNutrientInsights = async (\n  productCode?: string,\n  requestParams: InsightsRequestParams = {}\n): Promise<NutrientsInsight[]> => {\n  const params: InsightsRequestParams = {\n    ...requestParams,\n    insight_types: InsightType.nutrient_extraction,\n    annotated: false,\n  }\n  if (productCode) {\n    params[\"barcode\"] = productCode\n    insightIdByProductCode.setItem(productCode, null)\n  }\n  const response = await robotoff.insights<NutrientsInsight>(params)\n\n  response.insights.forEach((insight) => {\n    insightById.setItem(insight.id, insight)\n    insightIdByProductCode.setItem(insight.barcode, insight.id)\n  })\n\n  return response.insights\n}\n\n/**\n * Annotate an insight with data\n * @param data\n */\nexport const annotateNutrientsWithData = async (annotation: InsightAnnotationAnswer) => {\n  const servingSize = annotation.data[\"serving_size\"]?.value ?? null\n  // Clone the nutrients object to avoid mutating the original annotation.data\n  const clonedData = { ...annotation.data }\n  delete clonedData[\"serving_size\"]\n  const data: NutrientsAnnotationData = {\n    nutrients: clonedData,\n    nutrition_data_per: annotation.type,\n    serving_size: servingSize,\n  }\n  return await robotoff.annotateNutrients(\n    annotation.insightId,\n    AnnotationAnswer.ACCEPT_AND_ADD_DATA,\n    data\n  )\n}\n\n/**\n * Annotate an insight with annotation answer\n * @param insightId\n */\nexport const annotateNutrientWithoutData = async (\n  insightId: string,\n  annotation: AnnotationAnswer\n) => {\n  return await robotoff.annotateNutrients(insightId, annotation)\n}\n","import OpenFoodFacts from \"@openfoodfacts/openfoodfacts-nodejs\"\n\n/**\n * Taxonomies API\n */\nexport default {\n  /**\n   * Get the nutrients taxonomies\n   */\n  async nutrientsTaxonomies() {\n    const openFoodFacts = new OpenFoodFacts(fetch)\n    return await openFoodFacts.getNutrients()\n  },\n}\n","import type { NutrientTaxonomy } from \"../types/taxonomies\"\nimport { SignalMap } from \"../utils/signals\"\nimport { LoadingState } from \"../constants\"\nimport taxonomies from \"../api/taxonomies\"\nimport { Computed } from \"@lit-labs/signals\"\n\n/**\n * Store the loading state of the taxonomies to avoid multiple requests.\n */\nconst isLoading = new SignalMap<LoadingState>({\n  nutrients: LoadingState.NOT_LOADED,\n})\n\n/**\n * Store the taxonomies by id.\n *\n */\nexport const nutrientTaxonomyById = new SignalMap<NutrientTaxonomy>({})\n\n/**\n * Nutrient taxonomies\n */\nexport const nutrientTaxonomies = new Computed(() => {\n  const nutrientTaxonomyObj = nutrientTaxonomyById.get()\n  return Object.values(nutrientTaxonomyObj)\n})\n\n/**\n * Load the taxonomies if they are not already loaded.\n * @returns\n */\nexport const getTaxonomyNameByLang = (node: NutrientTaxonomy, lang: string) => {\n  if (!node) {\n    console.warn(\"getTaxonomyNameByLang called with undefined taxonomy\", { taxonomy: node })\n    return \"\"\n  }\n\n  return (\n    node.name[lang] ||\n    node.name[\"en\"] ||\n    node.name[\"xx\"] ||\n    (console.warn(\"No name found for taxonomy\", { taxonomy: node, lang }), \"\")\n  )\n}\n\n/**\n * Get the name of a taxonomy by its id and lang.\n * If the lang is not available, it returns the english name.\n * If the id is not available, it returns an empty string.\n */\nexport const getTaxonomyNameByIdAndLang = (id: string, lang: string) => {\n  const taxonomy = nutrientTaxonomyById.getItem(id)\n  return getTaxonomyNameByLang(taxonomy, lang)\n}\n\n/**\n * Get the unit of a taxonomy by its id.\n * If the id is not available, it returns undefined.\n */\nexport const getTaxonomyUnitById = (id: string): string | undefined => {\n  const taxonomy = nutrientTaxonomyById.getItem(id)\n  if (!taxonomy) {\n    return\n  }\n  return taxonomy?.unit?.en\n}\n\n/**\n * Fetch the nutrients taxonomies and store them in the signal.\nk\n */\nexport const fetchNutrientsTaxonomies = async () => {\n  if (isLoading.getItem(\"nutrients\") != LoadingState.NOT_LOADED) {\n    return\n  }\n  isLoading.setItem(\"nutrients\", LoadingState.LOADING)\n  const response = await taxonomies.nutrientsTaxonomies()\n\n  Object.entries(response).forEach(([key, value]) => {\n    const id = key.replace(\"zz:\", \"\")\n    nutrientTaxonomyById.setItem(id, { ...value, id })\n  })\n  isLoading.setItem(\"nutrients\", LoadingState.LOADED)\n}\n","import { InsightAnnotationSize } from \"../types/robotoff\"\nimport { isNullOrUndefined } from \".\"\nimport { getTaxonomyUnitById } from \"../signals/taxonomies\"\n\nexport enum Unit {\n  NULL = \"\",\n  MICROGRAMS = \"µg\",\n  MILIGRAMS = \"mg\",\n  GRAMS = \"g\",\n  KILOJOULES = \"kj\",\n  KILOCALORIES = \"kcal\",\n}\n\nexport const EDITABLE_UNITS = [Unit.GRAMS, Unit.MILIGRAMS, Unit.MICROGRAMS]\n\nexport enum NutrientSuffix {\n  PER_100G = \"_100g\",\n  PER_SERVING = \"_serving\",\n}\nexport const NUTRIENT_SERVING_SIZE_KEY = \"serving_size\"\n\nexport const INSIGHTS_ANNOTATION_SIZE = Object.values(InsightAnnotationSize)\nexport const NUTRIENT_SUFFIX: Record<InsightAnnotationSize, NutrientSuffix> = {\n  [InsightAnnotationSize.CENTGRAMS]: NutrientSuffix.PER_100G,\n  [InsightAnnotationSize.SERVING]: NutrientSuffix.PER_SERVING,\n}\n\nexport const NUTRIENT_UNIT_SUFFIX = \"_unit\"\n\nexport enum ForcedNutrientKey {\n  ENERGY_KJ = \"energy-kj\",\n  ENERGY_KCAL = \"energy-kcal\",\n  ENERGY_FROM_FAT = \"energy-from-fat\",\n}\n\nexport const FORCED_UNITS_BY_NUTRIENTS_KEYS = {\n  [ForcedNutrientKey.ENERGY_KJ]: Unit.KILOJOULES,\n  [ForcedNutrientKey.ENERGY_KCAL]: Unit.KILOCALORIES,\n  [ForcedNutrientKey.ENERGY_FROM_FAT]: Unit.KILOJOULES,\n}\n\n/**\n * get the possible units for a nutrient key\n * @param key - the nutrient key\n * @param fallbackUnit - the unit to check if it is forced or not.\n * For example, if the unit is \"kj\", it will return [\"kj\"].\n * @returns\n */\nexport const getPossibleUnits = (key: string, fallbackUnit?: string | null) => {\n  if (key in FORCED_UNITS_BY_NUTRIENTS_KEYS) {\n    const forcedUnit = [FORCED_UNITS_BY_NUTRIENTS_KEYS[key as ForcedNutrientKey]]\n    return forcedUnit\n  }\n  if (isNullOrUndefined(fallbackUnit)) {\n    fallbackUnit = getTaxonomyUnitById(key)\n  }\n  if (!fallbackUnit) {\n    return []\n  }\n  if (EDITABLE_UNITS.includes(fallbackUnit as Unit)) {\n    return EDITABLE_UNITS\n  }\n  return [fallbackUnit]\n}\n\nexport const NUTRIENT_UNIT_NAME_PREFIX = \"unit__\"\n","import { Directive, directive } from \"lit/directive.js\"\nimport { type StyleInfo, styleMap } from \"lit-html/directives/style-map.js\"\nimport { getImageUrl } from \"../signals/app\"\n\n/**\n * A directive to set a background image.\n\n */\nexport class BackgroundImageDirective extends Directive {\n  render(fileName: string, otherStyle: Readonly<StyleInfo> = {}) {\n    return styleMap({\n      ...otherStyle,\n      \"background-image\": `url('${getImageUrl(fileName)}')`,\n    })\n  }\n}\n\nexport const backgroundImage = directive(BackgroundImageDirective)\n","import { css } from \"lit\"\n\nexport const FOLKSONOMY_INPUT = css`\n  input[type=\"text\"] {\n    width: 100%;\n    padding: 0.5rem;\n    border: 1px solid #ccc;\n    border-radius: 5px;\n    box-sizing: border-box;\n    font-size: 0.9rem;\n    height: 2.2rem;\n    background-color: rgb(252, 251, 251);\n  }\n\n  input[type=\"text\"]:focus {\n    outline: none;\n    border-color: #007bff;\n    box-shadow: 0 0 3px rgba(0, 123, 255, 0.5);\n  }\n`\n","import{noChange as t}from\"../lit-html.js\";import{directive as s,Directive as i,PartType as r}from\"../directive.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const e=s(class extends i{constructor(t){if(super(t),t.type!==r.ATTRIBUTE||\"class\"!==t.name||t.strings?.length>2)throw Error(\"`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.\")}render(t){return\" \"+Object.keys(t).filter((s=>t[s])).join(\" \")+\" \"}update(s,[i]){if(void 0===this.st){this.st=new Set,void 0!==s.strings&&(this.nt=new Set(s.strings.join(\" \").split(/\\s/).filter((t=>\"\"!==t))));for(const t in i)i[t]&&!this.nt?.has(t)&&this.st.add(t);return this.render(i)}const r=s.element.classList;for(const t of this.st)t in i||(r.remove(t),this.st.delete(t));for(const t in i){const s=!!i[t];s===this.st.has(t)||this.nt?.has(t)||(s?(r.add(t),this.st.add(t)):(r.remove(t),this.st.delete(t)))}return t}});export{e as classMap};\n//# sourceMappingURL=class-map.js.map\n","import { LitElement, html, css } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { FOLKSONOMY_INPUT } from \"../../styles/folksonomy-input\"\nimport { classMap } from \"lit/directives/class-map.js\"\nimport type { AutocompleteSuggestion, AutocompleteInputChangeEventDetail } from \"../../types\"\nimport { SAFE_BLUE } from \"../../utils/colors\"\nimport { randomIdGenerator } from \"../../utils\"\n\n/**\n * AutocompleteInput Component\n * @element autocomplete-input\n * @description A reusable autocomplete input field with suggestions.\n * @fires input-change - Fired when the input value changes.\n * @fires suggestion-select - Fired when a suggestion is selected.\n */\n@customElement(\"autocomplete-input\")\nexport class AutocompleteInput extends LitElement {\n  static override styles = [\n    FOLKSONOMY_INPUT,\n    css`\n      .autocomplete-wrapper {\n        width: 100%;\n        position: relative;\n      }\n\n      .autocomplete-list {\n        position: absolute;\n        background: #fff;\n        border: 1px solid #ccc;\n        border-top: none;\n        list-style-type: none;\n        padding: 0;\n        margin: 0;\n        max-height: 200px;\n        overflow-y: auto;\n        z-index: 9999;\n        width: 100%;\n      }\n\n      .autocomplete-item {\n        padding: 10px;\n        cursor: pointer;\n      }\n\n      .autocomplete-item:hover {\n        background-color: #f0f0f0;\n      }\n\n      .autocomplete-item.highlighted {\n        background-color: #e0e0e0;\n        font-weight: bold;\n      }\n\n      .autocomplete-item.not-found {\n        background-color: #f8f9fa;\n        border-top: 1px solid #ddd;\n        color: #007bff;\n        font-style: italic;\n        padding: 12px 10px;\n      }\n\n      .autocomplete-item.not-found:hover {\n        background-color: #e7f3ff;\n      }\n\n      .autocomplete-item.not-found.highlighted {\n        background-color: #d4ebff;\n        font-weight: normal;\n      }\n\n      .autocomplete-input:focus {\n        outline: none;\n        border-color: ${SAFE_BLUE};\n      }\n    `,\n  ]\n\n  /**\n   * Placeholder text for the input field.\n   */\n  @property({ type: String }) placeholder = \"\"\n\n  /**\n   * Current value of the input field.\n   */\n  @property({ type: String })\n  get value() {\n    return this._inputValue ?? \"\"\n  }\n  set value(newValue: string) {\n    this._inputValue = newValue\n    this.requestUpdate()\n  }\n\n  /**\n   * List of suggestions to display in the autocomplete dropdown.\n   * Each suggestion can be a string or an object with label and value properties.\n   */\n  @property({ type: Array }) suggestions: AutocompleteSuggestion[] = []\n\n  /**\n   * Whether to show a \"not found\" option when no suggestions match.\n   */\n  @property({ type: Boolean, attribute: \"show-not-found-option\" }) showNotFoundOption = false\n\n  /**\n   * Text to display for the \"not found\" option.\n   */\n  @property({ type: String, attribute: \"not-found-text\" }) notFoundText = \"Not found\"\n\n  /**\n   * Whether to show the suggestions dropdown.\n   * @private\n   */\n  @state() private showSuggestions = false\n\n  /**\n   * Index of the currently highlighted suggestion.\n   * @private\n   */\n  @state() private highlightedIndex = -1\n\n  /**\n   * Unique ID for the input field.\n   * @private\n   */\n  @state()\n  private _id: string = \"\"\n\n  @state()\n  private _inputValue: string = \"\"\n\n  /**\n   * ID for the suggestions list.\n   * @private\n   */\n  get suggestionId() {\n    return `autocomplete-list-${this._id}`\n  }\n\n  getSuggestionItemId(index: number) {\n    return `autocomplete-item-${this._id}-${index}`\n  }\n\n  /**\n   * Filtered suggestions based on the current input value.\n   * @private\n   */\n  get filteredSuggestions() {\n    return this.filterSuggestions(this.value)\n  }\n\n  /**\n   * Get suggestions including a \"not found\" option if no matches are found\n   * @private\n   */\n  get suggestionsWithNotFound() {\n    const filtered = this.filteredSuggestions\n    if (this.showNotFoundOption && filtered.length === 0 && this.value.trim().length > 0) {\n      return [\n        {\n          value: \"__NOT_FOUND__\",\n          label: this.notFoundText.replace(\"{value}\", this.value),\n          isNotFound: true,\n        },\n      ]\n    }\n    return filtered\n  }\n\n  override connectedCallback() {\n    super.connectedCallback()\n    this._id = randomIdGenerator()\n  }\n  /**\n   * Filters suggestions based on the input value.\n   * @param inputValue - The current input value.\n   * @returns Filtered suggestions that match the input value.\n   */\n  private filterSuggestions(inputValue: string): AutocompleteSuggestion[] {\n    if (!inputValue) return this.suggestions\n\n    return this.suggestions.filter((suggestion) => {\n      const suggestionText = this.getSuggestionTextToFilter(suggestion)\n      return suggestionText.includes(inputValue.toLowerCase())\n    })\n  }\n\n  getSuggestionTextToFilter(suggestion: AutocompleteSuggestion) {\n    const suggestionText = suggestion.label ?? suggestion.value\n    return suggestionText.toLowerCase()\n  }\n\n  /**\n   * Handles input changes and dispatches the \"input-change\" event.\n   * @param e - The input event.\n   */\n  private onInput(e: Event) {\n    const inputValue = (e.target as HTMLInputElement).value\n    this.value = inputValue\n    this.highlightedIndex = -1\n    const filteredSuggestions = this.filteredSuggestions\n    const suggestionsToShow = this.suggestionsWithNotFound\n    this.showSuggestions = suggestionsToShow.length > 0\n    // If there is only one suggestion and it matches the input value, consider it a notable match\n    const matching =\n      filteredSuggestions.length === 1 &&\n      this.getSuggestionTextToFilter(filteredSuggestions[0]) === this.value\n        ? filteredSuggestions[0]\n        : undefined\n    this.dispatchEvent(\n      new CustomEvent<AutocompleteInputChangeEventDetail>(\"input-change\", {\n        detail: {\n          value: inputValue,\n          filteredSuggestions,\n          matching,\n        },\n        bubbles: true,\n        composed: true,\n      })\n    )\n  }\n\n  /**\n   * Selects a suggestion and dispatches the \"suggestion-select\" event.\n   * @param suggestion - The selected suggestion.\n   */\n  private selectSuggestion(suggestion: AutocompleteSuggestion) {\n    // Don't change the input value for the \"not found\" special case\n    if (suggestion.value !== \"__NOT_FOUND__\") {\n      this._inputValue = suggestion.value\n    }\n    this.showSuggestions = false\n    this.dispatchEvent(\n      new CustomEvent<AutocompleteSuggestion>(\"suggestion-select\", {\n        detail: suggestion,\n        bubbles: true,\n        composed: true,\n      })\n    )\n  }\n\n  /**\n   * Selects a suggestion if it matches the input value.\n   * @returns The selected suggestion, if any.\n   **/\n  selectMatchingSuggestion() {\n    const suggestion = this.filteredSuggestions.find(\n      (suggestion) => this.getSuggestionTextToFilter(suggestion) === this.value\n    )\n    if (suggestion) {\n      this.selectSuggestion(suggestion)\n    }\n    return suggestion\n  }\n\n  /**\n   * Handles keyboard navigation for suggestions.\n   * @param e - The keyboard event.\n   */\n  private onKeyDown(e: KeyboardEvent) {\n    const suggestionsToShow = this.suggestionsWithNotFound\n    if (suggestionsToShow.length === 0) return\n\n    // Do it before check if we show suggestions because we want to be able to\n    if (!this.showSuggestions) {\n      if (e.key === \"Enter\") {\n        e.preventDefault()\n\n        // return selected Suggestion if it matches the input value\n        this.selectMatchingSuggestion()\n      }\n      return\n    }\n    switch (e.key) {\n      case \"ArrowDown\":\n        e.preventDefault()\n        this.highlightedIndex = Math.min(this.highlightedIndex + 1, suggestionsToShow.length - 1)\n        break\n      case \"ArrowUp\":\n        e.preventDefault()\n        this.highlightedIndex = Math.max(this.highlightedIndex - 1, -1)\n        break\n      case \"Enter\":\n        e.preventDefault()\n\n        // If a suggestion is highlighted, select it\n        if (this.highlightedIndex >= 0) {\n          this.selectSuggestion(suggestionsToShow[this.highlightedIndex])\n          // If no suggestion is highlighted, check if the input match exactly with one suggestion\n        } else {\n          this.selectMatchingSuggestion()\n        }\n        break\n      case \"Escape\":\n        e.preventDefault()\n        this.showSuggestions = false\n        break\n      case \"Tab\":\n        if (this.highlightedIndex >= 0) {\n          e.preventDefault()\n          this.selectSuggestion(suggestionsToShow[this.highlightedIndex])\n        }\n        break\n    }\n  }\n\n  onFocus() {\n    this.showSuggestions = this.suggestions.length > 0\n    this.highlightedIndex = -1\n  }\n\n  override render() {\n    return html`\n      <div class=\"autocomplete-wrapper\">\n        <input\n          id=${this._id}\n          type=\"text\"\n          class=\"autocomplete-input\"\n          .value=${this.value}\n          placeholder=${this.placeholder}\n          @input=${this.onInput}\n          @keydown=${this.onKeyDown}\n          @focus=${() => this.onFocus()}\n          @blur=${() => setTimeout(() => (this.showSuggestions = false), 150)}\n          aria-autocomplete=\"list\"\n          aria-controls=${this.suggestionId}\n          aria-expanded=${this.showSuggestions}\n          aria-activedescendant=${this.highlightedIndex >= 0\n            ? this.getSuggestionItemId(this.highlightedIndex)\n            : \"\"}\n          part=\"autocomplete-input\"\n        />\n        ${this.showSuggestions\n          ? html`<ul\n              class=\"autocomplete-list\"\n              id=${this.suggestionId}\n              role=\"listbox\"\n              part=\"autocomplete-input-list\"\n            >\n              ${this.suggestionsWithNotFound.map(\n                (s, index) =>\n                  html`<li\n                    class=\"autocomplete-item ${classMap({\n                      highlighted: index === this.highlightedIndex,\n                      \"not-found\": s.isNotFound === true,\n                    })}\"\n                    role=\"option\"\n                    id=${this.getSuggestionItemId(index)}\n                    @mousedown=${() => this.selectSuggestion(this.suggestionsWithNotFound[index])}\n                    @mouseenter=${() => (this.highlightedIndex = index)}\n                    aria-selected=${index === this.highlightedIndex}\n                  >\n                    ${s.label ?? s.value}\n                  </li>`\n              )}\n            </ul>`\n          : null}\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"autocomplete-input\": AutocompleteInput\n  }\n}\n","import { localized, msg } from \"@lit/localize\"\nimport { LitElement, html } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\n\n@customElement(\"suggestion-icon\")\n@localized()\nexport class SuggestionIcon extends LitElement {\n  /**\n   * Color of the icon\n   */\n  @property({ type: String })\n  color = \"#000000\"\n\n  /**\n   * Size of the icon\n   */\n  @property({ type: String })\n  size = \"16px\"\n\n  override render() {\n    return html`\n      <svg\n        width=${this.size}\n        height=${this.size}\n        viewBox=\"0 0 16 16\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n      >\n        <title>${msg(\"Suggestion icon\")}</title>\n        <g id=\"Suggestion\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n          <path\n            d=\"M15.7779156,8.17533871 L12.1810436,7.01918172 L11.0248605,3.42207109 C10.9819796,3.28959143 10.8590972,3.19999167 10.7198944,3.19999167 C10.5806916,3.19999167 10.4578092,3.28959143 10.4152483,3.42207109 L9.25906518,7.01918172 L5.66219324,8.17533871 C5.52939059,8.2178986 5.4397888,8.34077828 5.4397888,8.47997792 C5.4397888,8.61917755 5.52939059,8.74205723 5.66187324,8.78461712 L9.25874517,9.94077411 L10.4149283,13.5378847 C10.4578092,13.6703644 10.5806916,13.7599642 10.7198944,13.7599642 C10.8590972,13.7599642 10.9819796,13.6703644 11.0245405,13.5378847 L12.1807236,9.94077411 L15.7775956,8.78461712 C15.9103982,8.74205723 16,8.61917755 16,8.47997792 C16,8.34077828 15.9103982,8.2178986 15.7779156,8.17533871 Z M0.538570771,4.14366921 L3.02694054,4.97310705 L3.85639713,7.46142057 C3.899918,7.59198023 4.02184044,7.67998 4.1597632,7.67998 C4.29768595,7.67998 4.4199284,7.59198023 4.46312926,7.46110057 L5.29258585,4.97278705 L7.78095562,4.14334921 C7.91183824,4.10014932 7.99984,3.97790964 7.99984,3.83999 C7.99984,3.70207036 7.91183824,3.57983068 7.78095562,3.53631079 L5.29258585,2.70687295 L4.46312926,0.218559431 C4.4199284,0.0879997708 4.29768595,-9.76996262e-15 4.1597632,-9.76996262e-15 C4.02184044,-9.76996262e-15 3.89959799,0.0879997708 3.85639713,0.21887943 L3.02694054,2.70687295 L0.538570771,3.53631079 C0.407688154,3.58015068 0.319686394,3.70207036 0.319686394,3.83999 C0.319686394,3.97790964 0.407688154,4.10014932 0.538570771,4.14366921 Z M5.54091082,12.1759683 L3.77255545,11.5865298 L3.18310366,9.81885443 C3.1399028,9.68829477 3.01766035,9.599975 2.87973759,9.599975 C2.74181484,9.599975 2.61957239,9.68797477 2.57637153,9.81885443 L1.98691974,11.5865298 L0.218884378,12.1759683 C0.0883217664,12.2194882 0,12.3417279 0,12.4796475 C0,12.6175671 0.08800176,12.7398068 0.218884378,12.7833267 L1.98723974,13.3727652 L2.57637153,15.1404406 C2.6198924,15.2706802 2.74181484,15.359 2.87973759,15.359 C3.01766035,15.359 3.1399028,15.2710002 3.18310366,15.1401206 L3.77255545,13.3724452 L5.54091082,12.7830067 C5.67179344,12.7394868 5.7597952,12.6172471 5.7597952,12.4796475 C5.7597952,12.3420479 5.67179344,12.2194882 5.54091082,12.1759683 Z\"\n            id=\"Shape\"\n            fill=${this.color}\n            fill-rule=\"nonzero\"\n          ></path>\n        </g>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"suggestion-icon\": SuggestionIcon\n  }\n}\n","import { localized, msg } from \"@lit/localize\"\nimport { LitElement, html } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\n\n@customElement(\"add-icon\")\n@localized()\nexport class AddIcon extends LitElement {\n  /**\n   * Color of the icon\n   */\n  @property({ type: String })\n  color = \"#FFFFFF\"\n\n  /**\n   * Size of the icon\n   */\n  @property({ type: String })\n  size = \"20px\"\n\n  override render() {\n    return html`\n      <svg\n        width=${this.size}\n        height=${this.size}\n        viewBox=\"0 0 20 20\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n      >\n        <title>${msg(\"Add\")}</title>\n        <g id=\"Add\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n          <path\n            d=\"M10,0 C4.477,0 0,4.477 0,10 C0,15.523 4.477,20 10,20 C15.523,20 20,15.523 20,10 C20,4.477 15.523,0 10,0 Z M13,11 L11,11 L11,13 C11,13.552 10.552,14 10,14 L10,14 C9.448,14 9,13.552 9,13 L9,11 L7,11 C6.448,11 6,10.552 6,10 L6,10 C6,9.448 6.448,9 7,9 L9,9 L9,7 C9,6.448 9.448,6 10,6 L10,6 C10.552,6 11,6.448 11,7 L11,9 L13,9 C13.552,9 14,9.448 14,10 L14,10 C14,10.552 13.552,11 13,11 Z\"\n            id=\"Shape\"\n            fill=${this.color}\n            fill-rule=\"nonzero\"\n          ></path>\n        </g>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"add-icon\": AddIcon\n  }\n}\n","import { LitElement, html } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { ICON_BASE } from \"../../styles/base\"\n\n@customElement(\"eye-visible-icon\")\nexport class EyeVisibleIcon extends LitElement {\n  static override styles = [ICON_BASE]\n  @property({ type: String })\n  color = \"currentColor\"\n\n  @property({ type: String })\n  size = \"30px\"\n\n  override render() {\n    return html`\n      <svg\n        width=${this.size}\n        height=${this.size}\n        viewBox=\"0 0 30 30\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n        fill=${this.color}\n      >\n        <title>Visible (eye)</title>\n        <g id=\"Visible-(eye)\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n          <path\n            d=\"M15.0022584,4 C5.6518347,4 1.21209194,12.0831308 0.134979845,14.3903814 C-0.0449932884,14.7753814 -0.0449932748,15.2219332 0.134979845,15.6069333 C1.21209194,17.9155582 5.6518347,26 15.0022584,26 C24.3199598,26 28.7626845,17.9740384 29.8588847,15.6337898 C30.0470384,15.2309148 30.0470384,14.7690852 29.8588847,14.3662102 C28.7626845,12.0259609 24.3199598,4 15.0022584,4 Z M15,8 C18.8654,8 22,11.1346 22,15 C22,18.8654 18.8654,22 15,22 C11.1346,22 8,18.8654 8,15 C8,11.1346 11.1346,8 15,8 Z M15,11 C12.790861,11 11,12.790861 11,15 C11,17.209139 12.790861,19 15,19 C17.209139,19 19,17.209139 19,15 C19,12.790861 17.209139,11 15,11 Z\"\n            id=\"Shape\"\n            fill-rule=\"nonzero\"\n            fill=${this.color}\n          ></path>\n        </g>\n      </svg>\n    `\n  }\n}\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"eye-visible-icon\": EyeVisibleIcon\n  }\n}\n","import { html, LitElement } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { ICON_BASE } from \"../../styles/base\"\n\n@customElement(\"eye-invisible-icon\")\nexport class EyeInvisibleIcon extends LitElement {\n  static override styles = [ICON_BASE]\n\n  @property({ type: String })\n  color = \"currentColor\"\n\n  @property({ type: String })\n  size = \"30px\"\n\n  override render() {\n    return html`\n      <svg\n        width=${this.size}\n        height=${this.size}\n        viewBox=\"0 0 30 30\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n        fill=${this.color}\n      >\n        <title>Invisible (eye)</title>\n        <g id=\"Invisible-(eye)\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n          <path\n            d=\"M1.7070312,0.59 L0.29296875,2.00406245 L28.2929687,30.0040623 L29.707031,28.59 L23.681641,22.5646093 C27.777456,19.7913713 29.799165,15.9136673 29.826172,15.8614843 C29.9396226,15.6951255 30.0000005,15.4983921 30.0000005,15.2970313 C30.0000005,15.0714747 29.9234465,14.8525938 29.783203,14.6759373 C29.679012,14.5082113 23.918297,5.29703125 15,5.29703125 C12.469857,5.29703125 10.199331,6.04722345 8.234375,7.11734375 L1.7070312,0.59 Z M15,8.29703125 C18.866,8.29703125 22,11.4310313 22,15.2970313 C22,16.8689873 21.470043,18.3098793 20.59375,19.4767193 L17.701172,16.5841403 C17.889655,16.1948503 18,15.7598773 18,15.2970313 C18,13.6400313 16.657,12.2970313 15,12.2970313 C14.537154,12.2970313 14.102181,12.4073763 13.712891,12.5958593 L10.820312,9.70328125 C11.987152,8.82698775 13.428044,8.29703125 15,8.29703125 Z M4.9511719,9.37320315 C1.9791583,11.8731563 0.27498083,14.5840623 0.21875,14.6739843 C0.0773890257,14.8509064 0.000265439074,15.0705709 -1.0658141e-13,15.2970313 C-1.0658141e-13,15.4905304 0.0564899972,15.6798222 0.16210938,15.8419533 C0.16340458,15.8439108 0.164706668,15.8458638 0.16601562,15.8478123 C0.18320928,15.8832923 5.0188313,25.2970313 15,25.2970313 C16.85,25.2970313 18.520531,24.9705153 20.019531,24.4435153 L17.431641,21.8536723 C16.672641,22.1356723 15.856,22.2970313 15,22.2970313 C11.134,22.2970313 8,19.1630313 8,15.2970313 C8,14.4410313 8.1613594,13.6243903 8.4433594,12.8653903 L4.9511719,9.37320315 Z\"\n            id=\"Shape\"\n            fill=${this.color}\n            fill-rule=\"nonzero\"\n          ></path>\n        </g>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"eye-invisible-icon\": EyeInvisibleIcon\n  }\n}\n","import { LitElement, css, html, nothing } from \"lit\"\nimport { customElement, property, query, state } from \"lit/decorators.js\"\nimport {\n  type NutrientsInsight,\n  type NutrientInsightDatum,\n  type InsightAnnotatationData,\n  type InsightAnnotationAnswer,\n  InsightAnnotationSize,\n  AnnotationAnswer,\n} from \"../../types/robotoff\"\nimport { localized, msg, str } from \"@lit/localize\"\nimport {\n  getTaxonomyNameByIdAndLang,\n  getTaxonomyUnitById,\n  getTaxonomyNameByLang,\n  nutrientTaxonomies,\n} from \"../../signals/taxonomies\"\nimport {\n  getPossibleUnits,\n  INSIGHTS_ANNOTATION_SIZE,\n  NUTRIENT_SERVING_SIZE_KEY,\n  NUTRIENT_SUFFIX,\n  NUTRIENT_UNIT_NAME_PREFIX,\n  NUTRIENT_UNIT_SUFFIX,\n} from \"../../utils/nutrient-extraction\"\nimport { EventType, SELECT_ICON_FILE_NAME, WHITE_SELECT_ICON_FILE_NAME } from \"../../constants\"\nimport { INPUT, SELECT } from \"../../styles/form\"\nimport { FLEX } from \"../../styles/utils\"\nimport { backgroundImage } from \"../../directives/background-image\"\nimport { ALERT } from \"../../styles/alert\"\nimport type { NutrimentsProductType } from \"../../types/openfoodfacts\"\nimport { GREEN } from \"../../utils/colors\"\nimport {\n  initDebounce,\n  removeUselessZeros,\n  setValueAndParentsObjectIfNotExists,\n  triggerSubmit,\n} from \"../../utils\"\nimport { nutrientsOrderByCountryCode, sortKeysByNutrientsOrder } from \"../../signals/openfoodfacts\"\nimport { countryCode, languageCode } from \"../../signals/app\"\n\nimport \"../shared/loading-button\"\nimport \"../shared/autocomplete-input\"\nimport \"../icons/suggestion\"\nimport \"../icons/add\"\nimport \"../icons/eye-visible\"\n\nimport \"../icons/eye-invisible\"\nimport type { AutocompleteInputChangeEvent, AutocompleteSuggestionSelectEvent } from \"../../types\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\n\nexport const ALLOWED_SPECIAL_VALUES = [\"\", \"-\", \"traces\"]\n\nexport type FormatedNutrimentData = {\n  value: string\n  unit: string\n}\n\n// A handy data structure for nutrients information\nexport type FormatedNutrients = {\n  // nutrients per 100g\n  \"100g\": Record<string, NutrientInsightDatum>\n  // nutrients per serving\n  serving: Record<string, FormatedNutrimentData>\n  // all nutrients present per 100g or serving\n  keys: string[]\n\n  servingSize?: string\n\n  robotoff: {\n    servingSize?: NutrientInsightDatum\n\n    // nutrients per 100g\n    \"100g\": Record<string, NutrientInsightDatum>\n    // nutrients per serving\n    serving: Record<string, NutrientInsightDatum>\n  }\n}\n/**\n * Variable store all size of the input to calculate the width of serving size input\n */\n\nconst SERVING_SIZE_SELECT_NAME = \"serving_size_select\"\n\n/**\n * Display a table of nutrients for a given product\n * @element robotoff-nutrient-extraction-form\n * @fires submit - when the user submit the form\n */\n@customElement(\"robotoff-nutrient-extraction-form\")\n@localized()\nexport class RobotoffNutrientExtractionForm extends LitElement {\n  static override styles = [\n    ...getButtonClasses([ButtonType.Chocolate]),\n    SELECT,\n    INPUT,\n    FLEX,\n    ALERT,\n    css`\n      :host {\n        font-weight: normal;\n        font-size: 1rem;\n      }\n      .inputs-wrapper {\n        display: grid;\n        grid-template-columns: 1fr auto auto;\n        align-items: end;\n        gap: 0.75rem;\n      }\n      .unit-wrapper {\n        width: 5rem;\n      }\n\n      .unit-wrapper select {\n        height: 2.5rem;\n        border-radius: 2.5rem;\n        padding-left: 1rem;\n        padding-right: 1rem;\n      }\n      .serving-size-wrapper {\n        gap: 0.3rem;\n      }\n      .serving-size-wrapper {\n        font-weight: bold;\n      }\n      .serving-size-wrapper input {\n        width: 12rem;\n        text-align: center;\n        box-sizing: border-box;\n      }\n\n      .submit-row {\n        display: grid;\n        grid-template-columns: 1fr 1fr;\n        gap: 0.5rem;\n      }\n\n      .submit-row .success-loading-button {\n        grid-column: 1 / 3;\n      }\n      .input-error-message {\n        display: block;\n        box-sizing: border-box;\n        margin-top: 0.2rem;\n        width: 100%;\n        font-size: 0.7rem;\n        color: var(--error-color, red);\n      }\n\n      .serving-size-selection label {\n        display: flex;\n        flex-direction: column;\n        text-align: center;\n      }\n      .serving-size-selection select {\n        margin-top: 0.25rem;\n        padding: 0.5rem 1rem;\n      }\n      .add-nutrient-row {\n        margin-top: 1rem;\n        margin-bottom: 1rem;\n      }\n      .add-nutrient-row select {\n        padding: 0.5rem 1rem;\n        width: 100%;\n      }\n\n      .input-label {\n        display: flex;\n        flex-direction: column;\n        gap: 0.2rem;\n        font-weight: bold;\n        font-size: 0.9rem;\n      }\n      .info {\n        display: block;\n        padding: 0;\n        width: 100%;\n      }\n\n      .nutrient-rows {\n        display: flex;\n        flex-direction: column;\n        gap: 0.75rem;\n      }\n      form,\n      .serving-size-selection {\n        max-width: 20rem;\n        width: 100%;\n      }\n      .nutrients-table {\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n        gap: 1rem;\n      }\n      .alert {\n        padding: 0.4rem;\n        margin-bottom: 0;\n      }\n      .toggle-nutrient-button-wrapper button {\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        width: 40px;\n        height: 40px;\n        border-radius: 50%;\n      }\n    `,\n  ]\n\n  /**\n   * Nutriments data\n   */\n  @property({ type: Object, attribute: \"nutriments-data\", reflect: true })\n  nutrimentsData?: NutrimentsProductType\n\n  /**\n   * The insight to edit\n   */\n  @property({ type: Object, reflect: true })\n  insight?: NutrientsInsight\n\n  /**\n   * Insight type\n   */\n  @state()\n  insightAnnotationSize: InsightAnnotationSize = InsightAnnotationSize.CENTGRAMS\n\n  /**\n   * Error message by key\n   *\n   */\n  @state()\n  private errors: Record<string, string> = {}\n\n  /**\n   * Loading state for buttons\n   */\n  @property({ type: Number, reflect: true })\n  loading?: AnnotationAnswer\n  /**\n   * Serving size value to display\n   */\n  @state()\n  private _servingSizeValue = \"\"\n\n  /**\n   * Formated Nutrients\n   */\n  @state()\n  private nutrients?: FormatedNutrients\n\n  /**\n   * Input hidden by nutrient code\n   */\n  @state()\n  private inputHiddenBySizeAndNutrientKey: Record<InsightAnnotationSize, Record<string, boolean>> =\n    {\n      \"100g\": {},\n      serving: {},\n    }\n\n  @state()\n  private debounceUpdatedInsight = initDebounce(() => {\n    this.onUpdateInsight()\n  })\n\n  /**\n   * Autocomplete value\n   */\n  @state()\n  autocompleteValue: string = \"\"\n\n  /**\n   * Form element\n   */\n  @query(\"form\")\n  private form?: HTMLFormElement\n\n  /**\n   * Serving size input\n   */\n  @query(`input[name='${NUTRIENT_SERVING_SIZE_KEY}']`)\n  private servingSizeInput?: HTMLInputElement\n\n  /**\n   * Country code\n   */\n  get countryCode() {\n    return countryCode.get()\n  }\n\n  /**\n   * Nutrients order by country code\n   */\n  get nutrientsOrder() {\n    return nutrientsOrderByCountryCode.getItem(this.countryCode)\n  }\n\n  /**\n   * Update properties when the insight is updated\n   *\n   */\n  onUpdateInsight = () => {\n    // Update the serving size value to dislay\n    this._servingSizeValue = this.insight!.data.nutrients.serving_size?.value || \"\"\n    // Update the insight type by checking the nutrient keys\n    this.insightAnnotationSize = Object.keys(this.insight!.data.nutrients).filter((key) =>\n      key.endsWith(NUTRIENT_SUFFIX[InsightAnnotationSize.CENTGRAMS])\n    ).length\n      ? InsightAnnotationSize.CENTGRAMS\n      : InsightAnnotationSize.SERVING\n\n    // Update the nutrients\n    this.updateFormatedNutrients()\n    this.inputHiddenBySizeAndNutrientKey = {\n      [InsightAnnotationSize.CENTGRAMS]: {},\n      [InsightAnnotationSize.SERVING]: {},\n    }\n  }\n\n  /**\n   * Update the insight type on connected callback\n   */\n  override connectedCallback() {\n    super.connectedCallback()\n    this.onUpdateInsight()\n  }\n\n  /**\n   * Update the insight type on attribute changed callback\n   */\n  override attributeChangedCallback(name: string, oldval: string, newval: string) {\n    super.attributeChangedCallback(name, oldval, newval)\n    if ([\"insight\", \"nutriments-data\"].includes(name)) {\n      this.debounceUpdatedInsight()\n    }\n  }\n\n  /**\n   * Process robotoff data from insight\n   * @param nutrients - The nutrients object to update\n   * @param insight - The insight data\n   * @returns Set of nutrient keys found\n   */\n  private processRobotoffData(\n    nutrients: FormatedNutrients,\n    insight: NutrientsInsight\n  ): Set<string> {\n    const keysSet = new Set<string>()\n\n    Object.entries(insight.data.nutrients)\n      // Sort by start position to keep the same order as the image\n      .sort((entryA, entryB) => entryA[1].start - entryB[1].start)\n      .forEach(([key, value]) => {\n        let nutrientKey\n        if (key.endsWith(NUTRIENT_SUFFIX[InsightAnnotationSize.CENTGRAMS])) {\n          nutrientKey = key.replace(NUTRIENT_SUFFIX[InsightAnnotationSize.CENTGRAMS], \"\")\n          nutrients.robotoff[InsightAnnotationSize.CENTGRAMS][nutrientKey] = value\n        } else if (key.endsWith(NUTRIENT_SUFFIX[InsightAnnotationSize.SERVING])) {\n          nutrientKey = key.replace(NUTRIENT_SUFFIX[InsightAnnotationSize.SERVING], \"\")\n          nutrients.robotoff[InsightAnnotationSize.SERVING][nutrientKey] = value\n        } else if (key === NUTRIENT_SERVING_SIZE_KEY) {\n          nutrients.robotoff.servingSize = value\n          nutrients.servingSize = value?.value\n          return\n        } else {\n          console.log(\"Unknown nutrient key\", key, value)\n          return\n        }\n        keysSet.add(nutrientKey)\n      })\n\n    return keysSet\n  }\n\n  /**\n   * Process serving size data from nutrimentsData\n   * @param nutrients - The nutrients object to update\n   * @param nutrimentsData - The nutriments data\n   */\n  private processServingSize(\n    nutrients: FormatedNutrients,\n    nutrimentsData: NutrimentsProductType\n  ): void {\n    // Add serving size data\n    if (nutrimentsData.serving_size) {\n      nutrients.servingSize = nutrimentsData.serving_size\n    }\n  }\n\n  /**\n   * Process nutrient data from nutrimentsData\n   * @param nutrients - The nutrients object to update\n   * @param nutrimentsData - The nutriments data\n   * @returns Set of nutrient keys found\n   */\n  private processNutrimentData(\n    nutrients: FormatedNutrients,\n    nutrimentsData: NutrimentsProductType\n  ): Set<string> {\n    const nutrientsOrder = this.nutrientsOrder\n    console.log(\"nutrientsOrder\", nutrientsOrder)\n    const keySet = new Set<string>()\n\n    // Check if nutriments data is available\n    if (!nutrimentsData.nutriments) {\n      return keySet\n    }\n\n    // Process nutrients\n    INSIGHTS_ANNOTATION_SIZE.forEach((size) => {\n      const suffix = NUTRIENT_SUFFIX[size]\n      const keys = Object.entries(nutrimentsData.nutriments).filter(([key]) => key.endsWith(suffix))\n      keys.forEach(([key, value]) => {\n        const nutrientKey = key.replace(suffix, \"\")\n        // Check if we have to show the nutrient in the edit form\n        if (!nutrientsOrder?.[nutrientKey]) {\n          return\n        }\n        const nutrientUnitKey = `${nutrientKey}${NUTRIENT_UNIT_SUFFIX}`\n        nutrients[size][nutrientKey] = {\n          value: value.toString(),\n          unit: nutrimentsData.nutriments[nutrientUnitKey] as string,\n        }\n        keySet.add(nutrientKey)\n      })\n    })\n    return keySet\n  }\n\n  /**\n   * Initialize empty nutrients structure\n   * @returns Empty nutrients structure\n   */\n  private initializeNutrientsStructure(): FormatedNutrients {\n    return {\n      servingSize: undefined,\n      keys: [],\n      \"100g\": {},\n      serving: {},\n      robotoff: {\n        servingSize: undefined,\n        \"100g\": {},\n        serving: {},\n      },\n    }\n  }\n\n  /**\n   * Add a key to the nutrients keys set\n   * @param keyToAdd - The key to add\n   */\n  addKeysSet(keyToAdd: string): void {\n    const keysSet = new Set(this.nutrients!.keys)\n    keysSet.add(keyToAdd)\n    this.nutrients!.keys = Array.from(keysSet)\n  }\n\n  /**\n   * Process the keys set to sort it and remove unwanted keys\n   * @param nutrients - The nutrients to process\n   * @param keysSet - The keys set to process\n   */\n  processKeysSet(nutrients: FormatedNutrients, keysSet: Set<string>): void {\n    const countryKeys = nutrientsOrderByCountryCode.getItem(this.countryCode) ?? {}\n    // Add needed keys from country keys\n    Object.keys(countryKeys)\n      .filter((key) => countryKeys[key].displayInEditForm)\n      // Remove alcohol key because it is weird to display it everytime\n      .filter((key) => key !== \"alcohol\")\n      .forEach((key) => keysSet.add(key))\n\n    // Transform set to array\n    let keys = Array.from(keysSet)\n\n    // Filter keys\n    keys = keys\n      // Remove keys nutrition-score until is not removed from API\n      .filter((key) => !/^nutrition-score/.test(key))\n      // Remove energy key because it will be computed from energy-kj\n      .filter((key) => key !== \"energy\")\n\n    // Sort keys and set them to nutrients\n    nutrients.keys = sortKeysByNutrientsOrder(this.countryCode, keys)\n  }\n\n  /**\n   * Update the nutrients in a formated way to manipulate it easily in the template\n   * @returns {FormatedNutrients}\n   */\n  updateFormatedNutrients(): FormatedNutrients {\n    // Initialize nutrients structure\n    const nutrients = this.initializeNutrientsStructure()\n    let keysSet = new Set<string>()\n\n    // Process robotoff data if available\n    if (this.insight) {\n      keysSet = this.processRobotoffData(nutrients, this.insight)\n    }\n\n    // Process nutriment data if available\n    if (this.nutrimentsData) {\n      // Process serving size\n      this.processServingSize(nutrients, this.nutrimentsData)\n\n      // Process nutrients data and merge keys\n      const nutrimentKeysSet = this.processNutrimentData(nutrients, this.nutrimentsData)\n      nutrimentKeysSet.forEach((key) => keysSet.add(key))\n    }\n\n    // Convert keys set to array and sort it based on the nutrients order\n    this.processKeysSet(nutrients, keysSet)\n\n    this.nutrients = nutrients\n    return this.nutrients\n  }\n\n  getInputValueName = (key: string, column: InsightAnnotationSize) => `${key}_${column}`\n  getInputUnitName = (key: string, column: InsightAnnotationSize) =>\n    `${NUTRIENT_UNIT_NAME_PREFIX}${this.getInputValueName(key, column)}`\n\n  addRobotoffSuggestionForServingSize() {\n    const robotoffSuggestion = this.nutrients?.robotoff.servingSize\n    if (!robotoffSuggestion?.value) {\n      return\n    }\n    this.nutrients!.servingSize = robotoffSuggestion.value\n    if (robotoffSuggestion.unit) {\n      this.nutrients!.servingSize += ` ${robotoffSuggestion.unit}`\n    }\n    this.servingSizeInput!.value = this.nutrients!.servingSize\n    this.requestUpdate()\n  }\n\n  setUnitInput(key: string, column: InsightAnnotationSize, unit?: string) {\n    const possibleUnits = getPossibleUnits(key)\n    // check if robotoffSuggestion.unit is valid to not override the unit with an unvalid one\n    const isRobotoffSuggestionUnitValid = possibleUnits.includes(unit ?? \"\")\n    if (isRobotoffSuggestionUnitValid) {\n      const selectInputUnit = this.shadowRoot!.querySelector<HTMLInputElement>(\n        `select[name=\"${this.getInputUnitName(key, column)}\"]`\n      )\n      if (selectInputUnit) {\n        selectInputUnit.value = unit ?? \"\"\n      }\n    }\n  }\n  addRobotoffSuggestion(key: string, column: InsightAnnotationSize) {\n    const robotoffSuggestion = this.nutrients?.robotoff[column][key]\n    if (!robotoffSuggestion?.value) {\n      return\n    }\n\n    setValueAndParentsObjectIfNotExists(\n      this.nutrients!,\n      `${column}.${key}.value`,\n      robotoffSuggestion.value\n    )\n    if (robotoffSuggestion.unit) {\n      this.nutrients![column][key].unit = robotoffSuggestion.unit\n    }\n    this.setUnitInput(key, column, robotoffSuggestion.unit)\n    this.requestUpdate()\n  }\n  renderRobotoffSuggestionForNutrient(key: string, column: InsightAnnotationSize) {\n    const robotoffSuggestion = this.nutrients?.robotoff[column][key]\n    const answer = this.nutrients![column][key]\n    return this.renderRobotoffSuggestion(\n      () => this.addRobotoffSuggestion(key, column),\n      robotoffSuggestion,\n      answer\n    )\n  }\n\n  renderRobotoffSuggestionForServingSize() {\n    const robotoffSuggestion: { value: string; unit?: string } = this.nutrients!.robotoff\n      .servingSize ?? { value: \"\" }\n    const robotoffServingSize = robotoffSuggestion.unit\n      ? `${robotoffSuggestion.value} ${robotoffSuggestion.unit!}`\n      : robotoffSuggestion.value\n    const answer = { value: this.nutrients!.servingSize! }\n    return this.renderRobotoffSuggestion(\n      () => this.addRobotoffSuggestionForServingSize(),\n      {\n        value: robotoffServingSize,\n      },\n      answer\n    )\n  }\n\n  /**\n   * Render the robotoff suggestion button.\n   * If the suggestion is already in the answers, return nothing.\n   * If the suggestion is not in the answers, return a button to add the suggestion.\n   * @param onClick - the function to call when the button is clicked\n   * @param robotoffSuggestion - the robotoff suggestion\n   * @param answer - the answer\n   * @returns the robotoff suggestion button\n   * @\n   */\n  renderRobotoffSuggestion(\n    onClick: () => void,\n    robotoffSuggestion?: { value: string; unit?: string },\n    answer?: { value: string; unit?: string }\n  ) {\n    const suggestionValue = removeUselessZeros(robotoffSuggestion?.value ?? \"\")\n    const value = removeUselessZeros(answer?.value ?? \"\")\n    if (\n      // Check if suggestion is already in the answers\n      // Check if the unit is the same or if the suggestion has no unit\n      // Return nothing if the suggestion is already in the answers\n      !suggestionValue ||\n      (value === suggestionValue &&\n        (!robotoffSuggestion!.unit || answer?.unit === robotoffSuggestion!.unit))\n    ) {\n      return nothing\n    }\n\n    const text = `${robotoffSuggestion!.value} ${robotoffSuggestion!.unit ?? \"\"}`\n    return html`<button\n      type=\"button\"\n      class=\"alert success with-icons\"\n      @click=${() => onClick()}\n      title=${msg(str`Replace current value by ${text}`)}\n    >\n      <suggestion-icon size=\"16px\" color=${GREEN}></suggestion-icon>\n      <span>${text}</span>\n      <add-icon size=\"16px\" color=${GREEN}></add-icon>\n    </button>`\n  }\n\n  /**\n   * Render the inputs for the given nutrient key and column\n   * @param nutrients - The nutrients to render\n   * @returns\n   */\n  renderRows() {\n    const nutrients = this.nutrients!\n    return nutrients.keys.map((key) => {\n      return html`\n        <div>\n          <div>\n            ${this.renderInputs(\n              key,\n              this.insightAnnotationSize,\n              nutrients[this.insightAnnotationSize][key]\n            )}\n          </div>\n\n          <div>${this.renderRobotoffSuggestionForNutrient(key, this.insightAnnotationSize)}</div>\n        </div>\n      `\n    })\n  }\n\n  /**\n   * Render the unit input for the given key and column.\n   * We use a method instead a component to have input in form data when submitting.\n   * @param key The key of the nutrient.\n   * @param column The column of the nutrient.\n   * @param nutrient The nutrient to render.\n   * @returns The rendered inputs.\n   */\n  renderUnit(\n    key: string,\n    column: InsightAnnotationSize,\n    nutrient: Pick<NutrientInsightDatum, \"unit\"> | undefined,\n    disabled = false\n  ) {\n    const possibleUnits = getPossibleUnits(key, nutrient?.unit)\n    const inputName = this.getInputUnitName(key, column)\n    const currentUnit = nutrient?.unit ?? getTaxonomyUnitById(key)\n    const selectsClasses = \"select chocolate unit-select\"\n    if (possibleUnits.length > 1) {\n      return html`\n        <select\n          name=${inputName}\n          class=${selectsClasses}\n          style=${backgroundImage(WHITE_SELECT_ICON_FILE_NAME)}\n          ?disabled=${disabled}\n        >\n          ${possibleUnits.map(\n            (unit) =>\n              html`<option value=\"${unit}\" ?selected=${unit === currentUnit}>${unit}</option>`\n          )}\n        </select>\n      `\n    } else if (possibleUnits[0]) {\n      return html`<input\n          type=\"hidden\"\n          name=\"${inputName}\"\n          .value=\"${possibleUnits[0]}\"\n          ?disabled=${disabled}\n        />\n        <select\n          class=${selectsClasses}\n          disabled\n          style=${backgroundImage(WHITE_SELECT_ICON_FILE_NAME)}\n        >\n          <option value=\"${possibleUnits[0]}\" selected>${possibleUnits[0]}</option>\n        </select>`\n    } else {\n      return nothing\n    }\n  }\n\n  /**\n   * Render the nutrient value inputs for the given key and column.\n   * We use a method instead a component to have input in form data when submitting.\n   * @param key The key of the nutrient.\n   * @param column The column of the nutrient.\n   * @param nutrient The nutrient to render.\n   * @returns The inputs for the given key and column.\n   */\n  renderInputs(\n    key: string,\n    column: InsightAnnotationSize,\n    nutrient: { value: number | string; unit: string } | undefined\n  ) {\n    const inputName = this.getInputValueName(key, column)\n    const value = nutrient?.value.toString() ?? \"\"\n    const label = getTaxonomyNameByIdAndLang(key, languageCode.get())\n    const isHidden = this.inputHiddenBySizeAndNutrientKey[column][key]\n\n    return html`\n      <div class=\"inputs-wrapper\">\n        <div>\n          <label class=\"input-label\">\n            <div>${label}</div>\n            ${isHidden\n              ? html`\n                  <input type=\"hidden\" name=\"${inputName}\" value=\"-\" />\n                  <input\n                    type=\"text\"\n                    value=\"-\"\n                    title=\"${msg(\"value\")}\"\n                    class=\"input input-nutritional-value cappucino\"\n                    disabled\n                  />\n                `\n              : html`<input\n                  type=\"text\"\n                  name=\"${inputName}\"\n                  .value=\"${value}\"\n                  title=\"${msg(\"value\")}\"\n                  class=\"input input-nutritional-value cappucino\"\n                />`}\n          </label>\n        </div>\n\n        <div title=${msg(\"unit\")} class=\"unit-wrapper\">\n          ${this.renderUnit(key, column, nutrient, isHidden)}\n        </div>\n        ${this.renderToggleNutrientButton(column, key)}\n      </div>\n      ${this.errors[inputName]\n        ? html`<span class=\"input-error-message\" role=\"alert\">${this.errors[inputName]}</span>`\n        : nothing}\n    `\n  }\n\n  /**\n   * Emit a custom submit event to submit the form data well formatted.\n   *\n   * @param insightAnnotationAnswer\n   */\n  emitSubmitEvent(insightAnnotationAnswer: InsightAnnotationAnswer) {\n    this.dispatchEvent(\n      new CustomEvent(EventType.SUBMIT, {\n        bubbles: true,\n        composed: true,\n        detail: insightAnnotationAnswer,\n      })\n    )\n  }\n\n  isUnitInput(key: string) {\n    return key.startsWith(NUTRIENT_UNIT_NAME_PREFIX)\n  }\n\n  /**\n   * Validate the input value.\n   */\n  validateInputValue(value: string | null): {\n    error?: string\n    value?: string\n  } {\n    const valueCleaned = value?.replace(\" \", \"\").replace(\",\", \".\") ?? \"\"\n\n    // Check if the value is a special value\n    if (ALLOWED_SPECIAL_VALUES.includes(valueCleaned)) {\n      return {\n        value: valueCleaned,\n      }\n    }\n    // Check if the value is a number and a multiple of 0.01. Replace < by nothing to allow to enter a value like <1\n    const numberValue = Number(valueCleaned.replace(/^</gm, \"\"))\n    if (isNaN(numberValue)) {\n      return {\n        error: msg(\"Error: Invalid value.\"),\n      }\n    }\n\n    return {\n      value: valueCleaned,\n    }\n  }\n\n  /**\n   * Validate the form data.\n   * It will return the form data well formatted.\n   */\n  validateFormData(data: InsightAnnotatationData): {\n    isValid: boolean\n    validatedData: InsightAnnotatationData\n  } {\n    this.errors = {}\n    for (const [key, item] of Object.entries(data)) {\n      // Skip serving size inputs\n      if (key === NUTRIENT_SERVING_SIZE_KEY) {\n        continue\n      }\n\n      const { error, value } = this.validateInputValue(item.value)\n\n      if (error) {\n        this.errors[key] = error\n      } else {\n        item.value = value!\n      }\n    }\n\n    // raise error if there is any error\n    if (Object.keys(this.errors).length > 0) {\n      return { isValid: false, validatedData: data }\n    }\n    return { isValid: true, validatedData: data }\n  }\n\n  /**\n   * Submit the form data.\n   * It will send the data to the server.\n   */\n  submitFormData(formData: FormData, column: InsightAnnotationSize) {\n    const nutrientAnotationForm: InsightAnnotatationData = {}\n    const formValues = formData.entries()\n\n    const servingSizeInputValue = this.servingSizeInput!.value!\n\n    // Add servingSize\n    nutrientAnotationForm[NUTRIENT_SERVING_SIZE_KEY] = {\n      value: servingSizeInputValue,\n      unit: null,\n    }\n\n    for (const [key, value] of formValues) {\n      let name = key\n      const isUnit = this.isUnitInput(name)\n      if (isUnit) {\n        name = name.replace(NUTRIENT_UNIT_NAME_PREFIX, \"\")\n      }\n\n      if (!nutrientAnotationForm[name]) {\n        nutrientAnotationForm[name] = {\n          value: \"\",\n          unit: null,\n        }\n      }\n      nutrientAnotationForm[name][isUnit ? \"unit\" : \"value\"] = value as string\n    }\n\n    const { isValid, validatedData } = this.validateFormData(nutrientAnotationForm)\n    if (!isValid) {\n      return\n    }\n\n    this.emitSubmitEvent({\n      type: column,\n      data: validatedData!,\n      insightId: this.insight!.id,\n    })\n  }\n\n  /**\n   * Handle the change event of the annotation type selection.\n   * It will update the annotation type.\n   */\n  onInsightAnnotationSizeChange(event: Event) {\n    const input = event.target as HTMLInputElement\n    const value = input.value as InsightAnnotationSize\n    this.insightAnnotationSize = value\n  }\n  /**\n   * Handle the click event of the skip button.\n   *\n   * It will emit a skip event.\n   */\n  onSkip() {\n    this.dispatchEvent(new CustomEvent(EventType.SKIP))\n  }\n  /**\n   * Handle the click event of the refuse button.\n   *\n   * It will emit a refuse event.\n   */\n  onRefuse() {\n    this.dispatchEvent(new CustomEvent(EventType.REFUSE))\n  }\n\n  /**\n   * Render the submit row.\n   * It will render a submit button.\n   */\n  renderSubmitRow() {\n    const isLoading = Boolean(this.loading)\n    const isAcceptLoading =\n      isLoading &&\n      [AnnotationAnswer.ACCEPT, AnnotationAnswer.ACCEPT_AND_ADD_DATA].includes(this.loading!)\n\n    return html`\n      <div class=\"submit-row\">\n        <!-- Trigger the submit event manually because lit component doesn't dispatch the submit event even if button is type submit -->\n        <loading-button\n          type=\"submit\"\n          class=\"success-loading-button\"\n          css-classes=\"button success-button\"\n          .loading=${isAcceptLoading}\n          .disabled=${isLoading}\n          @click=${() => triggerSubmit(this.form!)}\n          label=\"${msg(\"Submit\")}\"\n        ></loading-button>\n        <loading-button\n          .loading=${this.loading === AnnotationAnswer.SKIP}\n          .disabled=${isLoading}\n          css-classes=\"button white-button\"\n          @click=${this.onSkip}\n          label=${msg(\"Skip\")}\n        ></loading-button>\n        <loading-button\n          css-classes=\"button danger-button\"\n          .loading=${this.loading === AnnotationAnswer.REFUSE}\n          .disabled=${isLoading}\n          @click=${this.onRefuse}\n          label=${msg(\"Invalidate image\")}\n        ></loading-button>\n      </div>\n    `\n  }\n\n  onChangeServingSize(event: Event) {\n    const input = event.target as HTMLInputElement\n    const value = input.value\n    this._servingSizeValue = value\n  }\n\n  renderServingSizeInput() {\n    const servingSize = this.nutrients!.servingSize ?? \"\"\n    return html`<div class=\"\">\n      <label class=\"serving-size-wrapper flex align-center flex-col\">\n        <span>${msg(\"Serving size\")}</span>\n        <input\n          class=\"input cappucino\"\n          name=${NUTRIENT_SERVING_SIZE_KEY}\n          type=\"text\"\n          .value=${servingSize}\n          @change=${this.onChangeServingSize}\n        />\n      </label>\n      ${this.renderRobotoffSuggestionForServingSize()}\n    </div> `\n  }\n\n  /**\n   * Render the annotation type selection.\n   * It will render a radio button for each annotation type.\n   */\n  renderInsightAnnotationSizeSelection() {\n    return html`\n      <div class=\"serving-size-selection\">\n        <label>\n          <span>${msg(\"Nutrition facts are displayed on the packaging:\")}</span>\n          <select\n            class=\"select\"\n            name=\"${SERVING_SIZE_SELECT_NAME}\"\n            @change=${this.onInsightAnnotationSizeChange}\n            style=${backgroundImage(SELECT_ICON_FILE_NAME)}\n          >\n            <option\n              value=\"${InsightAnnotationSize.CENTGRAMS}\"\n              ?selected=${this.insightAnnotationSize === InsightAnnotationSize.CENTGRAMS}\n            >\n              ${msg(\"per 100g\")}\n            </option>\n            <option\n              value=\"${InsightAnnotationSize.SERVING}\"\n              ?selected=${this.insightAnnotationSize === InsightAnnotationSize.SERVING}\n            >\n              <span>${msg(str`per specified serving \"${this._servingSizeValue}\"`)}</span>\n            </option>\n          </select>\n        </label>\n      </div>\n    `\n  }\n\n  onAddNutrient(event: AutocompleteSuggestionSelectEvent) {\n    const nutrientId = event.detail.value\n    // Set it to the autocomplete value to force the component to update even if value is the same\n    this.autocompleteValue = event.detail.label!\n\n    this.addKeysSet(nutrientId)\n\n    // Reset the autocomplete value after to force the component to update even if\n    requestAnimationFrame(() => {\n      this.autocompleteValue = \"\"\n    })\n  }\n\n  /**\n   * Handle the form submission.\n   * It will emit a custom submit event to submit the form data well formatted.\n   * It only sent the data for the column that was submitted.\n   * @param event\n   */\n  onSubmit(event: SubmitEvent) {\n    event.preventDefault()\n    event.stopPropagation()\n    const formData = new FormData(event.target as HTMLFormElement)\n    this.submitFormData(formData, this.insightAnnotationSize)\n  }\n\n  onAutocompleteInput(event: AutocompleteInputChangeEvent) {\n    this.autocompleteValue = event.detail.value\n  }\n\n  /**\n   * Render the row to add a new nutrient.\n   * @param alreadyAddedNutrients\n   */\n  renderAddNutrientRow(alreadyAddedNutrients: string[]) {\n    const lang = languageCode.get()\n    const filteredNutrientTaxonomies = nutrientTaxonomies\n      .get()\n      // filter out the nutrients that are already added to the table\n      .filter((nutrientTaxonomy) => !alreadyAddedNutrients.includes(nutrientTaxonomy.id))\n      // map to the format expected by the autocomplete-input component\n      .map((nutrientTaxonomy) => ({\n        id: nutrientTaxonomy.id,\n        label: getTaxonomyNameByLang(nutrientTaxonomy, lang),\n        value: nutrientTaxonomy.id,\n      }))\n      // sort the nutrients by label\n      .sort((a, b) => a.label.localeCompare(b.label))\n\n    // if there are no nutrients to add, don't render the row\n    if (filteredNutrientTaxonomies.length === 0) {\n      return nothing\n    }\n\n    return html`\n      <div class=\"add-nutrient-row\">\n        <autocomplete-input\n          placeholder=\"${msg(\"Add a nutrient\")}\"\n          .value=${this.autocompleteValue}\n          @input-change=${(event: AutocompleteInputChangeEvent) => this.onAutocompleteInput(event)}\n          .suggestions=${filteredNutrientTaxonomies}\n          @suggestion-select=${this.onAddNutrient}\n        ></autocomplete-input>\n      </div>\n    `\n  }\n\n  /**\n   * Render the table with the nutrients data.\n   */\n  renderTable() {\n    const nutrients = this.nutrients!\n    return html`\n      <div>\n        <div class=\"nutrient-rows\">${this.renderRows()}</div>\n        <div>${this.renderAddNutrientRow(nutrients.keys)}</div>\n        <div>${this.renderSubmitRow()}</div>\n      </div>\n    `\n  }\n  /**\n   * Toggle the nutrient visibility.\n   */\n  toggleNutrient(column: InsightAnnotationSize, nutrientKey: string) {\n    // Implement the logic to toggle the nutrient visibility\n    this.inputHiddenBySizeAndNutrientKey[column][nutrientKey] =\n      !this.inputHiddenBySizeAndNutrientKey[column][nutrientKey]\n\n    this.requestUpdate()\n  }\n\n  /**\n   * Render the toggle nutrient button.\n   */\n  renderToggleNutrientButton(column: InsightAnnotationSize, nutrientKey: string) {\n    const isHidden = this.inputHiddenBySizeAndNutrientKey[column][nutrientKey]\n    return html`\n      <div class=\"toggle-nutrient-button-wrapper\">\n        <button\n          type=\"button\"\n          class=\"button chocolate-button\"\n          @click=${() => this.toggleNutrient(column, nutrientKey)}\n        >\n          ${isHidden\n            ? html`<eye-invisible-icon size=\"18px\"></eye-invisible-icon>`\n            : html` <eye-visible-icon size=\"18px\"></eye-visible-icon>`}\n        </button>\n      </div>\n    `\n  }\n\n  /**\n   * Render the component.\n   */\n  override render() {\n    return html`\n      <div class=\"nutrients-table\">\n        <div>${this.renderServingSizeInput()}</div>\n        <div>${this.renderInsightAnnotationSizeSelection()}</div>\n\n        <form @submit=${this.onSubmit}>\n          <div class=\"flex justify-center\">${this.renderTable()}</div>\n        </form>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"robotoff-nutrient-extraction-form\": RobotoffNutrientExtractionForm\n  }\n}\n","import { STATIC_HOST } from \"../constants\"\n\nexport enum ProductFields {\n  IMAGE_INGREDIENTS_URL = \"image_ingredients_url\",\n  PRODUCT_NAME = \"product_name\",\n  NUTRIMENTS = \"nutriments\",\n}\n/**\n * Gets the full image URL by replacing the '400.jpg' suffix with 'full.jpg'.\n * @param {string} imageUrl - The original image URL.\n * @returns {string} The full image URL.\n */\nexport const getFullImageUrl = (imageUrl?: string): string | undefined => {\n  if (!imageUrl) {\n    return undefined\n  }\n  return imageUrl.replace(/400.jpg$/, \"full.jpg\")\n}\n\nexport const KP_ATTRIBUTE_IMG = (img: string) => `${STATIC_HOST}/images/attributes/dist/${img}`\n","import{nothing as t}from\"../lit-html.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o=o=>o??t;export{o as ifDefined};\n//# sourceMappingURL=if-defined.js.map\n","import { LitElement } from \"lit\"\nimport type { Constructor } from \".\"\nimport { property } from \"lit/decorators.js\"\nimport { languageCode } from \"../signals/app\"\n\n/**\n * Interface for the LanguageCodesMixin.\n */\nexport interface LanguageCodesMixinInterface {\n  languageCodes?: string[]\n  _languageCodes: string[]\n}\n\n/**\n * A mixin that provides language code functionality to components.\n * It includes a languageCodes property and a getter for the language codes.\n * @mixin LanguageCodesMixin\n */\nexport const LanguageCodesMixin = <T extends Constructor<LitElement>>(\n  superClass: T\n): Constructor<LanguageCodesMixinInterface> & T => {\n  class LanguageCodesMixin extends superClass {\n    /**\n     * The language codes for the component.\n     * @type {string[] | undefined}\n     */\n    @property({ type: Array, attribute: \"language-codes\", reflect: true })\n    languageCodes?: string[]\n\n    /**\n     * Gets the language codes, defaulting to the current locale if not set.\n     * @returns {string[]} The language codes.\n     */\n    get _languageCodes() {\n      return this.languageCodes || [languageCode.get()]\n    }\n  }\n\n  return LanguageCodesMixin as Constructor<LanguageCodesMixinInterface> & T\n}\n","import { LitElement } from \"lit\"\nimport type { Constructor } from \".\"\nimport { property } from \"lit/decorators.js\"\nimport { countryCode } from \"../signals/app\"\n\n/**\n * Interface for the CountryCodeMixin.\n */\nexport interface CountryCodeMixinInterface {\n  countryCode?: string\n  _countryCode: string\n}\n\n/**\n * A mixin that provides country code functionality to components.\n * It includes a countryCode property and a getter for the country code.\n * @mixin CountryCodesMixin\n */\nexport const CountryCodeMixin = <T extends Constructor<LitElement>>(\n  superClass: T\n): Constructor<CountryCodeMixinInterface> & T => {\n  class CountryCodeMixin extends superClass {\n    /**\n     * The country code for the component.\n     * @type {string | undefined}\n     */\n    @property({ type: String, attribute: \"country-codes\", reflect: true })\n    countryCode?: string\n\n    /**\n     * Gets the country code, defaulting to the current locale if not set.\n     * @returns {string} The country code.\n     */\n    get _countryCode() {\n      return this.countryCode || countryCode.get()\n    }\n  }\n\n  return CountryCodeMixin as Constructor<CountryCodeMixinInterface> & T\n}\n","import { html, LitElement } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { ICON_BASE } from \"../../styles/base\"\n\n/**\n * External link icon component\n */\n@customElement(\"external-link-icon\")\nexport class ExternalLinkIcon extends LitElement {\n  static override styles = [ICON_BASE]\n\n  @property({ type: String })\n  color = \"currentColor\"\n\n  @property({ type: String })\n  size = \"16px\"\n\n  override render() {\n    return html`\n      <svg\n        width=${this.size}\n        height=${this.size}\n        viewBox=\"0 0 16 16\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n      >\n        <title>External link</title>\n        <g id=\"External-link\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n          <path\n            d=\"M15.085556,0.000370762406 C15.0524534,0.00141697617 15.0194351,0.00431337214 14.9866559,0.00904638777 L10.6610695,0.00904638777 C10.3406923,0.00451536035 10.0426935,0.172842877 9.88118266,0.44957304 C9.71967181,0.726303203 9.71967181,1.0685622 9.88118266,1.34529236 C10.0426935,1.62202252 10.3406923,1.79035004 10.6610695,1.78581901 L12.9583327,1.78581901 L4.70276137,10.0415655 C4.47068619,10.2643881 4.37720105,10.5952667 4.45835987,10.906593 C4.53951869,11.2179193 4.78263955,11.4610453 5.09395927,11.5422057 C5.40527898,11.6233662 5.73615053,11.529879 5.95896837,11.2977988 L14.2145393,3.04205278 L14.2145393,5.33936426 C14.2100084,5.65974827 14.3783323,5.95775341 14.6550566,6.11926769 C14.9317809,6.28078197 15.2740326,6.28078197 15.5507569,6.11926769 C15.8274812,5.95775341 15.9958051,5.65974827 15.9912742,5.33936426 L15.9912742,1.0102161 C16.0270842,0.751330008 15.9470966,0.489808079 15.7725984,0.295248373 C15.5981001,0.100688668 15.3467928,-0.00717209219 15.085556,0.000370762406 Z M1.77739509,0.0089571655 C0.806353686,0.0089571655 0.00066020321,0.814756982 0.00066020321,1.78581901 L0.00066020321,14.2232274 C0.00066020321,15.1942896 0.806353686,16 1.77739509,16 L14.2145393,16 C15.1855809,16 15.9913634,15.1942896 15.9913634,14.2232274 L15.9913634,8.89290951 C15.9958051,8.57252549 15.8274812,8.27452035 15.5507569,8.11300607 C15.2740326,7.95149179 14.9317809,7.95149179 14.6550566,8.11300607 C14.3783323,8.27452035 14.2100084,8.57252549 14.2145393,8.89290951 L14.2145393,14.2232274 L1.77739509,14.2232274 L1.77739509,1.78581901 L7.10759976,1.78581901 C7.42797696,1.79035004 7.72597578,1.62202252 7.88748663,1.34529236 C8.04899748,1.0685622 8.04899748,0.726303203 7.88748663,0.44957304 C7.72597578,0.172842877 7.42797696,0.00451536035 7.10759976,0.0089571655 L1.77739509,0.0089571655 Z\"\n            id=\"Shape\"\n            fill=${this.color}\n            fill-rule=\"nonzero\"\n          ></path>\n        </g>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"external-link-icon\": ExternalLinkIcon\n  }\n}\n","import { LitElement, html, css, nothing } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { msg } from \"@lit/localize\"\nimport { openfoodfactsApiUrl } from \"../../signals/openfoodfacts\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\nimport \"../icons/external-link\"\n\n/**\n * A button component that displays as a link with a link icon.\n * Takes a product-code property and generates the appropriate link.\n */\n@customElement(\"product-link-button\")\nexport class ProductLinkButton extends LitElement {\n  static override styles = [\n    getButtonClasses([ButtonType.LINK]),\n    css`\n      :host {\n        display: inline-block;\n      }\n    `,\n  ]\n\n  /**\n   * The product code to link to\n   */\n  @property({ type: String, attribute: \"product-code\", reflect: true })\n  productCode: string | undefined\n\n  get productUrl() {\n    return `${openfoodfactsApiUrl.get()}/product/${this.productCode}`\n  }\n\n  override render() {\n    if (!this.productCode) {\n      console.error(\"Product code is required\")\n      return nothing\n    }\n\n    return html`\n      <a href=\"${this.productUrl}\" target=\"_blank\" rel=\"noopener noreferrer\">\n        <button class=\"link-button button with-icon small\">\n          <external-link-icon></external-link-icon>\n          <span>${msg(\"View Product\")}</span>\n        </button>\n      </a>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"product-link-button\": ProductLinkButton\n  }\n}\n","import { html, LitElement, nothing, type TemplateResult } from \"lit\"\nimport type { Constructor } from \".\"\nimport { property } from \"lit/decorators.js\"\nimport \"../components/shared/product-link-button\"\n\n/**\n * Interface for the DisplayProductLinkMixin.\n */\nexport interface DisplayProductLinkMixinInterface {\n  displayProductLink?: boolean\n\n  renderProductLink(productCode: string): TemplateResult | typeof nothing\n}\n\n/**\n * A mixin that provides display product link functionality to components.\n * It includes a displayProductLink property and a getter for the display product link value.\n * @mixin DisplayProductLinkMixin\n */\nexport const DisplayProductLinkMixin = <T extends Constructor<LitElement>>(\n  superClass: T\n): Constructor<DisplayProductLinkMixinInterface> & T => {\n  class DisplayProductLinkMixin extends superClass {\n    /**\n     * Whether to display the product link.\n     * @type {boolean | undefined}\n     */\n    @property({ type: Boolean, attribute: \"display-product-link\", reflect: true })\n    displayProductLink: boolean = false\n\n    renderProductLink(productCode: string) {\n      if (!this.displayProductLink) {\n        return nothing\n      }\n      return html`<product-link-button product-code=\"${productCode}\"></product-link-button>`\n    }\n  }\n\n  return DisplayProductLinkMixin as Constructor<DisplayProductLinkMixinInterface> & T\n}\n","import { Task } from \"@lit/task\"\nimport { css, html, LitElement, nothing } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport {\n  annotateNutrientsWithData,\n  annotateNutrientWithoutData,\n  fetchNutrientInsights,\n  insightById,\n} from \"../../signals/nutrient-extraction\"\nimport \"./robotoff-nutrient-extraction-form\"\nimport \"../shared/zoomable-image\"\nimport \"../shared/loader\"\n\nimport { fetchNutrientsTaxonomies } from \"../../signals/taxonomies\"\nimport {\n  type NutrientsInsight,\n  type InsightAnnotationAnswer,\n  AnnotationAnswer,\n} from \"../../types/robotoff\"\nimport { BASE } from \"../../styles/base\"\nimport { getRobotoffImageUrl } from \"../../signals/robotoff\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\nimport { FLEX } from \"../../styles/utils\"\nimport { EventState, EventType } from \"../../constants\"\nimport type { BasicStateEventDetail } from \"../../types\"\nimport type { NutrimentsProductType } from \"../../types/openfoodfacts\"\nimport { fetchProduct } from \"../../api/openfoodfacts\"\nimport { ProductFields } from \"../../utils/openfoodfacts\"\nimport { fetchNutrientsOrderByCountryCode } from \"../../signals/openfoodfacts\"\nimport { LoadingWithTimeoutMixin } from \"../../mixins/loading-with-timeout-mixin\"\nimport { ifDefined } from \"lit-html/directives/if-defined.js\"\nimport { Breakpoints } from \"../../utils/breakpoints\"\nimport { LanguageCodesMixin } from \"../../mixins/language-codes-mixin\"\nimport { CountryCodeMixin } from \"../../mixins/country-codes-mixin\"\nimport { DisplayProductLinkMixin } from \"../../mixins/display-product-link-mixin\"\nimport { localized, msg } from \"@lit/localize\"\nimport { languageCode } from \"../../signals/app\"\n\nconst IMAGE_MAX_WIDTH = 700\n/**\n * Robotoff Nutrients component\n * @element robotoff-nutrient-extraction\n * @part nutrients - The nutrients component\n * @part nutrients-content-wrapper - The nutrients content wrapper\n */\n@customElement(\"robotoff-nutrient-extraction\")\n@localized()\nexport class RobotoffNutrientExtraction extends DisplayProductLinkMixin(\n  LanguageCodesMixin(\n    CountryCodeMixin(LoadingWithTimeoutMixin(LitElement, undefined as AnnotationAnswer | undefined))\n  )\n) {\n  static override styles = [\n    BASE,\n    FLEX,\n    ...getButtonClasses([ButtonType.LINK]),\n    css`\n      .image-wrapper {\n        position: sticky;\n        z-index: 1;\n        top: 1rem;\n        display: flex;\n        align-items: center;\n        margin-bottom: 1rem;\n        background-color: white;\n        box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n        border-radius: 5px;\n        padding-left: 1rem;\n        padding-right: 1rem;\n        padding-bottom: 1rem;\n        box-sizing: border-box;\n        max-width: ${IMAGE_MAX_WIDTH}px;\n        width: 100%;\n      }\n\n      .nutrients {\n        container-type: inline-size;\n      }\n\n      .nutrients-content-wrapper {\n        position: relative;\n        display: flex;\n        align-items: start;\n        gap: 0.5rem 5rem;\n      }\n\n      @container (max-width: ${Breakpoints.MD}px) {\n        .nutrients-content-wrapper {\n          flex-direction: column;\n          justify-content: center;\n          align-items: center;\n        }\n      }\n      .nutrients product-link-button {\n        margin-bottom: 1rem;\n      }\n    `,\n  ]\n\n  /**\n   * The product code to get the insights for\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"product-code\", reflect: true })\n  productCode?: string = undefined\n\n  @state()\n  insightsIds: string[] = []\n\n  @state()\n  currentInsightIndex: number = 0\n\n  @state()\n  private nutrimentsData?: NutrimentsProductType\n\n  get currentInsightId() {\n    return this.insightsIds[this.currentInsightIndex]\n  }\n\n  get currentInsight() {\n    return insightById.getItem(this.currentInsightId)\n  }\n\n  /**\n   * Emit the state event\n   * @param {EventState} state\n   */\n  emitNutrientEvent(state: EventState) {\n    const detail: BasicStateEventDetail = {\n      state,\n    }\n    const event = new CustomEvent(EventType.NUTRIENT_STATE, {\n      detail,\n      bubbles: true,\n      composed: true,\n    })\n    this.dispatchEvent(event)\n  }\n\n  /**\n   * Task to get the insights for the given product code\n   * it will fetch the incomplete nutrients insights and the nutrients taxonomies\n   * @type {Task}\n   */\n  private _insightsTask = new Task(this, {\n    task: async ([productCode], {}) => {\n      this.emitNutrientEvent(EventState.LOADING)\n      const [insights] = await Promise.all([\n        fetchNutrientInsights(productCode, {\n          lc: this._languageCodes,\n        }),\n        fetchNutrientsTaxonomies(),\n        fetchNutrientsOrderByCountryCode(this._countryCode),\n      ])\n\n      this.insightsIds = insights.map((insight) => insight.id)\n      if (!this.insightsIds.length) {\n        this.emitNutrientEvent(EventState.NO_DATA)\n        return\n      }\n      this.emitNutrientEvent(EventState.HAS_DATA)\n      await this.loadInsight(0)\n    },\n    args: () => [this.productCode, this.countryCode, ...this._languageCodes],\n  })\n\n  async loadInsight(index: number) {\n    if (index >= this.insightsIds.length) {\n      this.emitNutrientEvent(EventState.FINISHED)\n      return\n    }\n    this.currentInsightIndex = index\n    const insight = this.currentInsight\n    await this.getProductNutriments(insight.barcode)\n  }\n\n  /**\n   * Get the product nutriments\n   * @param {string} productCode\n   * @returns {Promise<NutrimentsProductType>}\n   */\n  async getProductNutriments(productCode: string) {\n    this.nutrimentsData = undefined\n    const result = await fetchProduct<NutrimentsProductType>(productCode, {\n      fields: [ProductFields.NUTRIMENTS],\n      lc: languageCode.get(),\n    })\n    this.nutrimentsData = result.product\n    return result.product.nutriments\n  }\n\n  renderImage(insight: NutrientsInsight) {\n    if (!insight?.source_image) {\n      return nothing\n    }\n    const imgUrl = getRobotoffImageUrl(insight.source_image)\n    return html`\n      <div class=\"image-wrapper\">\n        <zoomable-image\n          src=${imgUrl}\n          .size=\"${{\n            height: \"35vh\",\n            width: \"100%\",\n            \"max-width\": `${IMAGE_MAX_WIDTH}px`,\n          }}\"\n          show-buttons\n        ></zoomable-image>\n      </div>\n    `\n  }\n\n  /**\n   * After the insight has been annotated\n   * Remove Loading state and emit event annotated\n   * Load the next insight\n   * @returns {Promise<void>}\n   */\n  async afterInsightAnnotation() {\n    await this.hideLoading()\n    this.emitNutrientEvent(EventState.ANNOTATED)\n    this.loadInsight(this.currentInsightIndex + 1)\n  }\n\n  /**\n   * Annotate the nutrients insights\n   * @returns {Promise<void>}\n   */\n  async onSubmit(event: CustomEvent<InsightAnnotationAnswer>) {\n    this.showLoading(AnnotationAnswer.ACCEPT_AND_ADD_DATA)\n    await annotateNutrientsWithData(event.detail)\n    await this.afterInsightAnnotation()\n  }\n\n  /**\n   * Refuse the current insight\n   */\n  async onRefuse() {\n    this.showLoading(AnnotationAnswer.REFUSE)\n    await annotateNutrientWithoutData(this.currentInsightId, AnnotationAnswer.REFUSE)\n    await this.afterInsightAnnotation()\n  }\n\n  /**\n   * Skip the current insight\n   */\n  async onSkip() {\n    this.showLoading(AnnotationAnswer.SKIP)\n    await annotateNutrientWithoutData(this.currentInsightId, AnnotationAnswer.SKIP)\n    await this.afterInsightAnnotation()\n  }\n  renderHeader(insight: NutrientsInsight) {\n    return html`\n      <div>\n        <h2>${msg(\"Help us correct the nutritional information\")}</h2>\n        ${this.renderProductLink(insight.barcode)}\n      </div>\n    `\n  }\n\n  override render() {\n    return this._insightsTask.render({\n      pending: () => html`<off-wc-loader></off-wc-loader>`,\n      complete: () => {\n        const insight = this.currentInsight\n        if (!insight) {\n          return html`<slot name=\"no-insight\"></slot>`\n        }\n        return html`\n          <div class=\"nutrients\" part=\"nutrients\">\n            ${this.renderHeader(insight)}\n            <div part=\"nutrients-content-wrapper\" class=\"nutrients-content-wrapper\">\n              ${this.renderImage(insight as NutrientsInsight)}\n              <robotoff-nutrient-extraction-form\n                loading=${ifDefined(this.loading) as AnnotationAnswer}\n                .nutrimentsData=\"${this.nutrimentsData}\"\n                .insight=\"${insight as NutrientsInsight}\"\n                @submit=\"${this.onSubmit}\"\n                @refuse=\"${this.onRefuse}\"\n                @skip=\"${this.onSkip}\"\n              ></robotoff-nutrient-extraction-form>\n            </div>\n          </div>\n        `\n      },\n      error: (error) => html`<p>Error: ${error}</p>`,\n    })\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"robotoff-nutrient-extraction\": RobotoffNutrientExtraction\n  }\n}\n","import { SignalMap } from \"../utils/signals\"\nimport robotoff from \"../api/robotoff\"\nimport {\n  InsightType,\n  type IngredientSpellcheckInsight,\n  type InsightsRequestParams,\n} from \"../types/robotoff\"\n\nexport const ingredientSpellcheckInsights = new SignalMap<IngredientSpellcheckInsight>({})\n\nexport async function fetchSpellcheckInsights(\n  productCode?: string,\n  requestParams: InsightsRequestParams = {}\n): Promise<IngredientSpellcheckInsight[]> {\n  let result\n  const params: InsightsRequestParams = {\n    ...requestParams,\n    insight_types: InsightType.ingredient_spellcheck,\n    annotated: false,\n  }\n  if (productCode) {\n    params[\"barcode\"] = productCode\n  }\n  try {\n    result = await robotoff.insights<IngredientSpellcheckInsight>(params)\n    result.insights.forEach((insight: IngredientSpellcheckInsight) => {\n      ingredientSpellcheckInsights.setItem(insight.id, insight)\n    })\n  } catch (error) {\n    console.error(\"Error fetching spellcheck insights:\", error)\n    return []\n  }\n  return result.insights\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n\n/**\n * @element check-icon\n */\n@customElement(\"check-icon\")\nexport class CheckIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 20px;\n      height: 20px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n\n  override render() {\n    return html`\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n        <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z\" />\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"check-icon\": CheckIcon\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n\n/**\n * @element cross-icon\n */\n@customElement(\"cross-icon\")\nexport class CrossIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 20px;\n      height: 20px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n\n  override render() {\n    return html`\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n        <path\n          d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\n        />\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"cross-icon\": CrossIcon\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n\n/**\n * @element skip-icon\n */\n@customElement(\"skip-icon\")\nexport class SkipIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 20px;\n      height: 20px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n\n  override render() {\n    return html`\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n        <path d=\"M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z\" />\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"skip-icon\": SkipIcon\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n\n/**\n * @element edit-icon\n */\n@customElement(\"edit-icon\")\nexport class EditIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 20px;\n      height: 20px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n\n  override render() {\n    return html`\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n        <path\n          d=\"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\"\n        />\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"edit-icon\": EditIcon\n  }\n}\n","import { css, LitElement } from \"lit\"\nimport { html } from \"lit-html\"\nimport { styleMap } from \"lit-html/directives/style-map.js\"\nimport { customElement, property } from \"lit/decorators.js\"\n\n/**\n * @element info-icon\n */\n@customElement(\"info-icon\")\nexport class InfoIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 20px;\n      height: 20px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n\n  @property({ type: Object, attribute: \"custom-styles\" })\n  customStyles = {}\n\n  override render() {\n    return html`\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        viewBox=\"0 0 24 24\"\n        style=\"${styleMap(this.customStyles)}\"\n        fill=\"currentColor\"\n        width=\"1em\"\n        height=\"1em\"\n        display=\"inline-block\"\n        font-size=\"24px\"\n        transition=\"fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms\"\n        flex-shrink=\"0\"\n        aria-hidden=\"true\"\n        focusable=\"false\"\n      >\n        <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n        <path\n          d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"\n        />\n      </svg>\n    `\n  }\n}\n","import { css, LitElement } from \"lit\"\nimport { html } from \"lit-html\"\nimport { customElement } from \"lit/decorators.js\"\nimport { SAFE_BLUE } from \"../../utils/colors\"\nimport \"../icons/info\"\nimport { Breakpoints } from \"../../utils/breakpoints\"\n\n/**\n * @element info-button\n */\n@customElement(\"info-button\")\nexport class InfoButton extends LitElement {\n  static override styles = css`\n    .info-button {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      background-color: ${SAFE_BLUE};\n      color: white;\n      border: none;\n      border-radius: 50%;\n      cursor: pointer;\n      width: 30px;\n      height: 30px;\n      padding: 5px;\n\n      @media (min-width: ${Breakpoints.SM}px) {\n        width: 40px;\n        height: 40px;\n        padding: 8px;\n      }\n    }\n    button:hover {\n      opacity: 0.8;\n    }\n  `\n\n  override render() {\n    return html`\n      <button class=\"info-button\">\n        <info-icon .custom-styles=\"${{ fill: \"white\" }}\"></info-icon>\n      </button>\n    `\n  }\n}\n","import { css } from \"lit\"\nimport { SAFE_DARKER_WHITE, SAFE_GREY } from \"../utils/colors\"\n\nexport const POPOVER = css`\n  .popover-wrapper {\n    position: relative;\n    cursor: pointer;\n    display: inline-block;\n  }\n\n  .popover {\n    position: absolute;\n    z-index: 10;\n    background-color: ${SAFE_DARKER_WHITE};\n    border: 1px solid ${SAFE_GREY};\n    border-radius: 4px;\n    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n    padding: 0.75rem;\n    max-width: 300px;\n    width: 100%;\n    height: auto;\n    top: 100%;\n    left: 50%;\n    transform: translateX(-50%);\n    margin-top: 0.5rem;\n    white-space: normal;\n    text-decoration: none;\n    color: inherit;\n  }\n\n  .popover::before,\n  .popover::after {\n    content: \"\";\n    position: absolute;\n    bottom: 100%;\n    left: 50%;\n    transform: translateX(-50%);\n    border: solid transparent;\n  }\n\n  .popover::before {\n    border-bottom-color: ${SAFE_GREY};\n    border-width: 8px;\n    margin-left: 0px;\n  }\n\n  .popover::after {\n    border-bottom-color: ${SAFE_DARKER_WHITE};\n    border-width: 7px;\n    margin-left: 0px;\n  }\n\n  .popover-content {\n    display: flex;\n    flex-direction: column;\n    gap: 0.5rem;\n  }\n\n  .popover-buttons {\n    display: flex;\n    gap: 0.5rem;\n    justify-content: flex-end;\n    margin-top: 0.5rem;\n  }\n\n  /* Position variants */\n  .popover.popover-top {\n    top: auto;\n    bottom: 100%;\n    margin-top: 0;\n    margin-bottom: 0.5rem;\n  }\n\n  .popover.popover-top::before,\n  .popover.popover-top::after {\n    top: 100%;\n    bottom: auto;\n  }\n\n  .popover.popover-top::before {\n    border-top-color: ${SAFE_GREY};\n    border-bottom-color: transparent;\n  }\n\n  .popover.popover-top::after {\n    border-top-color: ${SAFE_DARKER_WHITE};\n    border-bottom-color: transparent;\n  }\n\n  .popover.popover-left {\n    left: auto;\n    right: 100%;\n    transform: translateY(-50%);\n    top: 50%;\n    bottom: auto;\n    margin-top: 0;\n    margin-right: 1rem;\n  }\n\n  .popover.popover-left::before,\n  .popover.popover-left::after {\n    left: 100%;\n    right: auto;\n    transform: translateY(-50%);\n    top: 50%;\n    bottom: auto;\n    border-width: 8px 0 8px 8px;\n    border-color: transparent transparent transparent ${SAFE_GREY};\n  }\n\n  .popover.popover-right {\n    left: auto;\n    right: 0;\n    transform: none;\n  }\n\n  .popover.popover-right::before,\n  .popover.popover-right::after {\n    left: auto;\n    right: 20px;\n    transform: none;\n  }\n\n  .popover .button {\n    display: flex;\n  }\n`\n","import { css } from \"lit\"\nimport { SAFE_LIGHT_GREEN, SAFE_LIGHT_GREY, SAFE_LIGHT_RED } from \"../utils/colors\"\n\nexport const TEXT_CORRECTOR = css`\n  .text-section {\n    padding-bottom: 0.5rem;\n    border-bottom: 1px solid ${SAFE_LIGHT_GREY};\n    box-shadow: 0 0.5rem 2px -2px rgba(0, 0, 0, 0.1);\n  }\n\n  h2 {\n    font-size: 1.2rem;\n    margin-bottom: 0.5rem;\n  }\n\n  .text-content {\n    border-radius: 4px;\n    white-space: pre-wrap;\n    line-height: 1.5;\n  }\n\n  .deletion {\n    background-color: ${SAFE_LIGHT_RED};\n  }\n\n  .addition {\n    background-color: ${SAFE_LIGHT_GREEN};\n  }\n\n  .line-through {\n    text-decoration: line-through;\n  }\n`\n","import { directive } from \"lit/directive.js\"\nimport { AsyncDirective } from \"lit/async-directive.js\"\n\n/**\n * A Lit directive that detects clicks outside a specified element and triggers a callback function.\n */\n\n/**\n * A Lit directive that detects clicks outside a specified element and triggers a callback function.\n */\nclass ClickOutsideDirective extends AsyncDirective {\n  private element: HTMLElement | null = null\n  private callback: (() => void) | null = null\n  private clickIsTriggered: boolean = false\n\n  /**\n   * Initializes the ClickOutsideDirective.\n   * @param {any} part - The part information.\n   */\n  constructor(part: any) {\n    super(part)\n    this.element = part.element as HTMLElement\n    this.addEventListener()\n    this.clickIsTriggered = false\n  }\n\n  /**\n   * Renders the directive.\n   * @param {() => void} callback - The callback function to be called when a click outside the element is detected.\n   * @returns {HTMLElement | null} The element to which the directive is applied.\n   */\n  override render(callback: () => void) {\n    this.callback = callback\n    return this.element\n  }\n\n  /**\n   * Updates the directive.\n   * @param {any} part - The part information.\n   * @param {[() => void]} [callback] - The callback function to be called when a click outside the element is detected.\n   * @returns {HTMLElement | null} The element to which the directive is applied.\n   */\n  override update(part: any, [callback]: [() => void]) {\n    this.element = part.element as HTMLElement\n    return this.render(callback)\n  }\n\n  /**\n   * Catches the event click from the element.\n   * Use this trick because element.contains doesn't work with shadow dom\n   * @returns {void}\n   */\n  catchEventClickFromElement() {\n    this.clickIsTriggered = true\n  }\n\n  /**\n   * Cleans up the directive when it is disconnected.\n   */\n  override disconnected() {\n    this.removeEventListener()\n  }\n\n  /**\n   * Adds an event listener to detect clicks outside the element.\n   */\n  private addEventListener() {\n    // Add a small delay to ensure the event listener is added after the initial render\n    requestAnimationFrame(() => {\n      this.element!.addEventListener(\"click\", () => this.catchEventClickFromElement())\n      document.addEventListener(\"click\", this.handleClick)\n    })\n  }\n\n  /**\n   * Removes the event listener that detects clicks outside the element.\n   */\n  private removeEventListener() {\n    this.element!.removeEventListener(\"click\", () => this.catchEventClickFromElement)\n    document.removeEventListener(\"click\", this.handleClick)\n  }\n\n  /**\n   * Handles the click event to detect clicks outside the element.\n   * @param {MouseEvent} event - The mouse event.\n   */\n  private handleClick = () => {\n    // Use this trick because element.contains doesn't work with shadow dom\n    if (this.clickIsTriggered) {\n      this.clickIsTriggered = false\n      return\n    }\n    this.callback?.()\n  }\n}\n\n/**\n * Creates a Lit directive that detects clicks outside a specified element and triggers a callback function.\n * @returns {Directive} The clickOutside directive.\n */\nexport const clickOutside = directive(ClickOutsideDirective)\n","import type { Change } from \"diff\"\nimport { AnnotationAnswer } from \"./robotoff\"\nimport { EventState } from \"../constants\"\n\n/**\n * Enum for the type of change in the text\n */\nexport enum ChangeType {\n  ADDED = \"added\",\n  REMOVED = \"removed\",\n  CHANGED = \"changed\",\n}\n\n/**\n * Type for a change in the text with its index\n */\nexport type IndexedChange = Change & { index: number }\n\n/**\n * Type for a grouped change in the text\n * It allow to groupe additions, removals in \"changed\" type\n * For example, if the text is \"hello world\" and the correction is \"hello universe\"\n * The grouped change will be of type \"changed\" with the value \"world\" and the new value \"universe\n * instead of remove \"world\" and add \"universe\" separately\n */\nexport type IndexedGroupedChange = {\n  type: ChangeType\n  value?: string\n  oldValue?: string\n  newValue?: string\n  indexes: number[]\n  position: number\n}\n\n/**\n * Type for the event detail of the text corrector\n */\nexport type TextCorrectorEventDetail = {\n  correction?: string\n  annotation: AnnotationAnswer\n}\n\n/**\n * Type for the event of the text corrector\n *\n * It is a custom event with the detail of the text corrector\n */\nexport type TextCorrectorEvent = CustomEvent<TextCorrectorEventDetail>\n\n/**\n * Type for the event detail of the robotoff ingredients state\n *  It is a custom event with the detail of the robotoff ingredients state\n */\nexport type RobotoffIngredientsStateEventDetail = {\n  state: EventState\n  insightId?: string\n  productCode?: string\n} & Partial<TextCorrectorEventDetail>\n","import{nothing as t,noChange as i}from\"../lit-html.js\";import{Directive as r,PartType as s,directive as n}from\"../directive.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */class e extends r{constructor(i){if(super(i),this.it=t,i.type!==s.CHILD)throw Error(this.constructor.directiveName+\"() can only be used in child bindings\")}render(r){if(r===t||null==r)return this._t=void 0,this.it=r;if(r===i)return r;if(\"string\"!=typeof r)throw Error(this.constructor.directiveName+\"() called with a non-string value\");if(r===this.it)return this._t;this.it=r;const s=[r];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName=\"unsafeHTML\",e.resultType=1;const o=n(e);export{e as UnsafeHTMLDirective,o as unsafeHTML};\n//# sourceMappingURL=unsafe-html.js.map\n","/*! @license DOMPurify 3.2.7 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.7/LICENSE */\n\nconst {\n  entries,\n  setPrototypeOf,\n  isFrozen,\n  getPrototypeOf,\n  getOwnPropertyDescriptor\n} = Object;\nlet {\n  freeze,\n  seal,\n  create\n} = Object; // eslint-disable-line import/no-mutable-exports\nlet {\n  apply,\n  construct\n} = typeof Reflect !== 'undefined' && Reflect;\nif (!freeze) {\n  freeze = function freeze(x) {\n    return x;\n  };\n}\nif (!seal) {\n  seal = function seal(x) {\n    return x;\n  };\n}\nif (!apply) {\n  apply = function apply(func, thisArg) {\n    for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n      args[_key - 2] = arguments[_key];\n    }\n    return func.apply(thisArg, args);\n  };\n}\nif (!construct) {\n  construct = function construct(Func) {\n    for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n      args[_key2 - 1] = arguments[_key2];\n    }\n    return new Func(...args);\n  };\n}\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySplice = unapply(Array.prototype.splice);\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\nconst regExpTest = unapply(RegExp.prototype.test);\nconst typeErrorCreate = unconstruct(TypeError);\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param func - The function to be wrapped and called.\n * @returns A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(func) {\n  return function (thisArg) {\n    if (thisArg instanceof RegExp) {\n      thisArg.lastIndex = 0;\n    }\n    for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n      args[_key3 - 1] = arguments[_key3];\n    }\n    return apply(func, thisArg, args);\n  };\n}\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param func - The constructor function to be wrapped and called.\n * @returns A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(Func) {\n  return function () {\n    for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n      args[_key4] = arguments[_key4];\n    }\n    return construct(Func, args);\n  };\n}\n/**\n * Add properties to a lookup table\n *\n * @param set - The set to which elements will be added.\n * @param array - The array containing elements to be added to the set.\n * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns The modified set with added elements.\n */\nfunction addToSet(set, array) {\n  let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;\n  if (setPrototypeOf) {\n    // Make 'in' and truthy checks like Boolean(set.constructor)\n    // independent of any properties defined on Object.prototype.\n    // Prevent prototype setters from intercepting set as a this value.\n    setPrototypeOf(set, null);\n  }\n  let l = array.length;\n  while (l--) {\n    let element = array[l];\n    if (typeof element === 'string') {\n      const lcElement = transformCaseFunc(element);\n      if (lcElement !== element) {\n        // Config presets (e.g. tags.js, attrs.js) are immutable.\n        if (!isFrozen(array)) {\n          array[l] = lcElement;\n        }\n        element = lcElement;\n      }\n    }\n    set[element] = true;\n  }\n  return set;\n}\n/**\n * Clean up an array to harden against CSPP\n *\n * @param array - The array to be cleaned.\n * @returns The cleaned version of the array\n */\nfunction cleanArray(array) {\n  for (let index = 0; index < array.length; index++) {\n    const isPropertyExist = objectHasOwnProperty(array, index);\n    if (!isPropertyExist) {\n      array[index] = null;\n    }\n  }\n  return array;\n}\n/**\n * Shallow clone an object\n *\n * @param object - The object to be cloned.\n * @returns A new object that copies the original.\n */\nfunction clone(object) {\n  const newObject = create(null);\n  for (const [property, value] of entries(object)) {\n    const isPropertyExist = objectHasOwnProperty(object, property);\n    if (isPropertyExist) {\n      if (Array.isArray(value)) {\n        newObject[property] = cleanArray(value);\n      } else if (value && typeof value === 'object' && value.constructor === Object) {\n        newObject[property] = clone(value);\n      } else {\n        newObject[property] = value;\n      }\n    }\n  }\n  return newObject;\n}\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param object - The object to look up the getter function in its prototype chain.\n * @param prop - The property name for which to find the getter function.\n * @returns The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter(object, prop) {\n  while (object !== null) {\n    const desc = getOwnPropertyDescriptor(object, prop);\n    if (desc) {\n      if (desc.get) {\n        return unapply(desc.get);\n      }\n      if (typeof desc.value === 'function') {\n        return unapply(desc.value);\n      }\n    }\n    object = getPrototypeOf(object);\n  }\n  function fallbackValue() {\n    return null;\n  }\n  return fallbackValue;\n}\n\nconst html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);\nconst svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'slot', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);\nconst svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nconst svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);\nconst mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nconst mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);\nconst text = freeze(['#text']);\n\nconst html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);\nconst svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);\nconst mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);\nconst xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);\n\n// eslint-disable-next-line unicorn/better-regex\nconst MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nconst ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nconst TMPLIT_EXPR = seal(/\\$\\{[\\w\\W]*/gm); // eslint-disable-line unicorn/better-regex\nconst DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]+$/); // eslint-disable-line no-useless-escape\nconst ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nconst IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nconst IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nconst ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nconst DOCTYPE_NAME = seal(/^html$/i);\nconst CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n\nvar EXPRESSIONS = /*#__PURE__*/Object.freeze({\n  __proto__: null,\n  ARIA_ATTR: ARIA_ATTR,\n  ATTR_WHITESPACE: ATTR_WHITESPACE,\n  CUSTOM_ELEMENT: CUSTOM_ELEMENT,\n  DATA_ATTR: DATA_ATTR,\n  DOCTYPE_NAME: DOCTYPE_NAME,\n  ERB_EXPR: ERB_EXPR,\n  IS_ALLOWED_URI: IS_ALLOWED_URI,\n  IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,\n  MUSTACHE_EXPR: MUSTACHE_EXPR,\n  TMPLIT_EXPR: TMPLIT_EXPR\n});\n\n/* eslint-disable @typescript-eslint/indent */\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n  element: 1,\n  attribute: 2,\n  text: 3,\n  cdataSection: 4,\n  entityReference: 5,\n  // Deprecated\n  entityNode: 6,\n  // Deprecated\n  progressingInstruction: 7,\n  comment: 8,\n  document: 9,\n  documentType: 10,\n  documentFragment: 11,\n  notation: 12 // Deprecated\n};\nconst getGlobal = function getGlobal() {\n  return typeof window === 'undefined' ? null : window;\n};\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param trustedTypes The policy factory.\n * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {\n  if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\n    return null;\n  }\n  // Allow the callers to control the unique policy name\n  // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n  // Policy creation with duplicate names throws in Trusted Types.\n  let suffix = null;\n  const ATTR_NAME = 'data-tt-policy-suffix';\n  if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n    suffix = purifyHostElement.getAttribute(ATTR_NAME);\n  }\n  const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n  try {\n    return trustedTypes.createPolicy(policyName, {\n      createHTML(html) {\n        return html;\n      },\n      createScriptURL(scriptUrl) {\n        return scriptUrl;\n      }\n    });\n  } catch (_) {\n    // Policy creation failed (most likely another DOMPurify script has\n    // already run). Skip creating the policy, as this will only cause errors\n    // if TT are enforced.\n    console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\n    return null;\n  }\n};\nconst _createHooksMap = function _createHooksMap() {\n  return {\n    afterSanitizeAttributes: [],\n    afterSanitizeElements: [],\n    afterSanitizeShadowDOM: [],\n    beforeSanitizeAttributes: [],\n    beforeSanitizeElements: [],\n    beforeSanitizeShadowDOM: [],\n    uponSanitizeAttribute: [],\n    uponSanitizeElement: [],\n    uponSanitizeShadowNode: []\n  };\n};\nfunction createDOMPurify() {\n  let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\n  const DOMPurify = root => createDOMPurify(root);\n  DOMPurify.version = '3.2.7';\n  DOMPurify.removed = [];\n  if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {\n    // Not running in a browser, provide a factory function\n    // so that you can pass your own Window\n    DOMPurify.isSupported = false;\n    return DOMPurify;\n  }\n  let {\n    document\n  } = window;\n  const originalDocument = document;\n  const currentScript = originalDocument.currentScript;\n  const {\n    DocumentFragment,\n    HTMLTemplateElement,\n    Node,\n    Element,\n    NodeFilter,\n    NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n    HTMLFormElement,\n    DOMParser,\n    trustedTypes\n  } = window;\n  const ElementPrototype = Element.prototype;\n  const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n  const remove = lookupGetter(ElementPrototype, 'remove');\n  const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n  const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n  const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n  // As per issue #47, the web-components registry is inherited by a\n  // new document created via createHTMLDocument. As per the spec\n  // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n  // a new empty registry is used when creating a template contents owner\n  // document, so we use that as our parent document to ensure nothing\n  // is inherited.\n  if (typeof HTMLTemplateElement === 'function') {\n    const template = document.createElement('template');\n    if (template.content && template.content.ownerDocument) {\n      document = template.content.ownerDocument;\n    }\n  }\n  let trustedTypesPolicy;\n  let emptyHTML = '';\n  const {\n    implementation,\n    createNodeIterator,\n    createDocumentFragment,\n    getElementsByTagName\n  } = document;\n  const {\n    importNode\n  } = originalDocument;\n  let hooks = _createHooksMap();\n  /**\n   * Expose whether this browser supports running the full DOMPurify.\n   */\n  DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;\n  const {\n    MUSTACHE_EXPR,\n    ERB_EXPR,\n    TMPLIT_EXPR,\n    DATA_ATTR,\n    ARIA_ATTR,\n    IS_SCRIPT_OR_DATA,\n    ATTR_WHITESPACE,\n    CUSTOM_ELEMENT\n  } = EXPRESSIONS;\n  let {\n    IS_ALLOWED_URI: IS_ALLOWED_URI$1\n  } = EXPRESSIONS;\n  /**\n   * We consider the elements and attributes below to be safe. Ideally\n   * don't add any new ones but feel free to remove unwanted ones.\n   */\n  /* allowed element names */\n  let ALLOWED_TAGS = null;\n  const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);\n  /* Allowed attribute names */\n  let ALLOWED_ATTR = null;\n  const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);\n  /*\n   * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.\n   * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n   * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n   * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n   */\n  let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {\n    tagNameCheck: {\n      writable: true,\n      configurable: false,\n      enumerable: true,\n      value: null\n    },\n    attributeNameCheck: {\n      writable: true,\n      configurable: false,\n      enumerable: true,\n      value: null\n    },\n    allowCustomizedBuiltInElements: {\n      writable: true,\n      configurable: false,\n      enumerable: true,\n      value: false\n    }\n  }));\n  /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n  let FORBID_TAGS = null;\n  /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n  let FORBID_ATTR = null;\n  /* Decide if ARIA attributes are okay */\n  let ALLOW_ARIA_ATTR = true;\n  /* Decide if custom data attributes are okay */\n  let ALLOW_DATA_ATTR = true;\n  /* Decide if unknown protocols are okay */\n  let ALLOW_UNKNOWN_PROTOCOLS = false;\n  /* Decide if self-closing tags in attributes are allowed.\n   * Usually removed due to a mXSS issue in jQuery 3.0 */\n  let ALLOW_SELF_CLOSE_IN_ATTR = true;\n  /* Output should be safe for common template engines.\n   * This means, DOMPurify removes data attributes, mustaches and ERB\n   */\n  let SAFE_FOR_TEMPLATES = false;\n  /* Output should be safe even for XML used within HTML and alike.\n   * This means, DOMPurify removes comments when containing risky content.\n   */\n  let SAFE_FOR_XML = true;\n  /* Decide if document with <html>... should be returned */\n  let WHOLE_DOCUMENT = false;\n  /* Track whether config is already set on this instance of DOMPurify. */\n  let SET_CONFIG = false;\n  /* Decide if all elements (e.g. style, script) must be children of\n   * document.body. By default, browsers might move them to document.head */\n  let FORCE_BODY = false;\n  /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n   * string (or a TrustedHTML object if Trusted Types are supported).\n   * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n   */\n  let RETURN_DOM = false;\n  /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n   * string  (or a TrustedHTML object if Trusted Types are supported) */\n  let RETURN_DOM_FRAGMENT = false;\n  /* Try to return a Trusted Type object instead of a string, return a string in\n   * case Trusted Types are not supported  */\n  let RETURN_TRUSTED_TYPE = false;\n  /* Output should be free from DOM clobbering attacks?\n   * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n   */\n  let SANITIZE_DOM = true;\n  /* Achieve full DOM Clobbering protection by isolating the namespace of named\n   * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n   *\n   * HTML/DOM spec rules that enable DOM Clobbering:\n   *   - Named Access on Window (§7.3.3)\n   *   - DOM Tree Accessors (§3.1.5)\n   *   - Form Element Parent-Child Relations (§4.10.3)\n   *   - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n   *   - HTMLCollection (§4.2.10.2)\n   *\n   * Namespace isolation is implemented by prefixing `id` and `name` attributes\n   * with a constant string, i.e., `user-content-`\n   */\n  let SANITIZE_NAMED_PROPS = false;\n  const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n  /* Keep element content when removing element? */\n  let KEEP_CONTENT = true;\n  /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n   * of importing it into a new Document and returning a sanitized copy */\n  let IN_PLACE = false;\n  /* Allow usage of profiles like html, svg and mathMl */\n  let USE_PROFILES = {};\n  /* Tags to ignore content of when KEEP_CONTENT is true */\n  let FORBID_CONTENTS = null;\n  const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);\n  /* Tags that are safe for data: URIs */\n  let DATA_URI_TAGS = null;\n  const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);\n  /* Attributes safe for values like \"javascript:\" */\n  let URI_SAFE_ATTRIBUTES = null;\n  const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);\n  const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n  const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n  const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n  /* Document namespace */\n  let NAMESPACE = HTML_NAMESPACE;\n  let IS_EMPTY_INPUT = false;\n  /* Allowed XHTML+XML namespaces */\n  let ALLOWED_NAMESPACES = null;\n  const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);\n  let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);\n  let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);\n  // Certain elements are allowed in both SVG and HTML\n  // namespace. We need to specify them explicitly\n  // so that they don't get erroneously deleted from\n  // HTML namespace.\n  const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);\n  /* Parsing of strict XHTML documents */\n  let PARSER_MEDIA_TYPE = null;\n  const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n  const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n  let transformCaseFunc = null;\n  /* Keep a reference to config to pass to hooks */\n  let CONFIG = null;\n  /* Ideally, do not touch anything below this line */\n  /* ______________________________________________ */\n  const formElement = document.createElement('form');\n  const isRegexOrFunction = function isRegexOrFunction(testValue) {\n    return testValue instanceof RegExp || testValue instanceof Function;\n  };\n  /**\n   * _parseConfig\n   *\n   * @param cfg optional config literal\n   */\n  // eslint-disable-next-line complexity\n  const _parseConfig = function _parseConfig() {\n    let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n    if (CONFIG && CONFIG === cfg) {\n      return;\n    }\n    /* Shield configuration object from tampering */\n    if (!cfg || typeof cfg !== 'object') {\n      cfg = {};\n    }\n    /* Shield configuration object from prototype pollution */\n    cfg = clone(cfg);\n    PARSER_MEDIA_TYPE =\n    // eslint-disable-next-line unicorn/prefer-includes\n    SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;\n    // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n    transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;\n    /* Set configuration parameters */\n    ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;\n    ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;\n    ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;\n    URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;\n    DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;\n    FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;\n    FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});\n    FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});\n    USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;\n    ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n    ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n    ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n    ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n    SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n    SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n    WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n    RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n    RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n    RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n    FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n    SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n    SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n    KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n    IN_PLACE = cfg.IN_PLACE || false; // Default false\n    IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n    NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n    MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;\n    HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;\n    CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n    if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {\n      CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n    }\n    if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {\n      CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n    }\n    if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {\n      CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n    }\n    if (SAFE_FOR_TEMPLATES) {\n      ALLOW_DATA_ATTR = false;\n    }\n    if (RETURN_DOM_FRAGMENT) {\n      RETURN_DOM = true;\n    }\n    /* Parse profile info */\n    if (USE_PROFILES) {\n      ALLOWED_TAGS = addToSet({}, text);\n      ALLOWED_ATTR = [];\n      if (USE_PROFILES.html === true) {\n        addToSet(ALLOWED_TAGS, html$1);\n        addToSet(ALLOWED_ATTR, html);\n      }\n      if (USE_PROFILES.svg === true) {\n        addToSet(ALLOWED_TAGS, svg$1);\n        addToSet(ALLOWED_ATTR, svg);\n        addToSet(ALLOWED_ATTR, xml);\n      }\n      if (USE_PROFILES.svgFilters === true) {\n        addToSet(ALLOWED_TAGS, svgFilters);\n        addToSet(ALLOWED_ATTR, svg);\n        addToSet(ALLOWED_ATTR, xml);\n      }\n      if (USE_PROFILES.mathMl === true) {\n        addToSet(ALLOWED_TAGS, mathMl$1);\n        addToSet(ALLOWED_ATTR, mathMl);\n        addToSet(ALLOWED_ATTR, xml);\n      }\n    }\n    /* Merge configuration parameters */\n    if (cfg.ADD_TAGS) {\n      if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n        ALLOWED_TAGS = clone(ALLOWED_TAGS);\n      }\n      addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n    }\n    if (cfg.ADD_ATTR) {\n      if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n        ALLOWED_ATTR = clone(ALLOWED_ATTR);\n      }\n      addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n    }\n    if (cfg.ADD_URI_SAFE_ATTR) {\n      addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n    }\n    if (cfg.FORBID_CONTENTS) {\n      if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n        FORBID_CONTENTS = clone(FORBID_CONTENTS);\n      }\n      addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n    }\n    /* Add #text in case KEEP_CONTENT is set to true */\n    if (KEEP_CONTENT) {\n      ALLOWED_TAGS['#text'] = true;\n    }\n    /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n    if (WHOLE_DOCUMENT) {\n      addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n    }\n    /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n    if (ALLOWED_TAGS.table) {\n      addToSet(ALLOWED_TAGS, ['tbody']);\n      delete FORBID_TAGS.tbody;\n    }\n    if (cfg.TRUSTED_TYPES_POLICY) {\n      if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n        throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.');\n      }\n      if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n        throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.');\n      }\n      // Overwrite existing TrustedTypes policy.\n      trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n      // Sign local variables required by `sanitize`.\n      emptyHTML = trustedTypesPolicy.createHTML('');\n    } else {\n      // Uninitialized policy, attempt to initialize the internal dompurify policy.\n      if (trustedTypesPolicy === undefined) {\n        trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);\n      }\n      // If creating the internal policy succeeded sign internal variables.\n      if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n        emptyHTML = trustedTypesPolicy.createHTML('');\n      }\n    }\n    // Prevent further manipulation of configuration.\n    // Not available in IE8, Safari 5, etc.\n    if (freeze) {\n      freeze(cfg);\n    }\n    CONFIG = cfg;\n  };\n  /* Keep track of all possible SVG and MathML tags\n   * so that we can perform the namespace checks\n   * correctly. */\n  const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);\n  const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);\n  /**\n   * @param element a DOM element whose namespace is being checked\n   * @returns Return false if the element has a\n   *  namespace that a spec-compliant parser would never\n   *  return. Return true otherwise.\n   */\n  const _checkValidNamespace = function _checkValidNamespace(element) {\n    let parent = getParentNode(element);\n    // In JSDOM, if we're inside shadow DOM, then parentNode\n    // can be null. We just simulate parent in this case.\n    if (!parent || !parent.tagName) {\n      parent = {\n        namespaceURI: NAMESPACE,\n        tagName: 'template'\n      };\n    }\n    const tagName = stringToLowerCase(element.tagName);\n    const parentTagName = stringToLowerCase(parent.tagName);\n    if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n      return false;\n    }\n    if (element.namespaceURI === SVG_NAMESPACE) {\n      // The only way to switch from HTML namespace to SVG\n      // is via <svg>. If it happens via any other tag, then\n      // it should be killed.\n      if (parent.namespaceURI === HTML_NAMESPACE) {\n        return tagName === 'svg';\n      }\n      // The only way to switch from MathML to SVG is via`\n      // svg if parent is either <annotation-xml> or MathML\n      // text integration points.\n      if (parent.namespaceURI === MATHML_NAMESPACE) {\n        return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\n      }\n      // We only allow elements that are defined in SVG\n      // spec. All others are disallowed in SVG namespace.\n      return Boolean(ALL_SVG_TAGS[tagName]);\n    }\n    if (element.namespaceURI === MATHML_NAMESPACE) {\n      // The only way to switch from HTML namespace to MathML\n      // is via <math>. If it happens via any other tag, then\n      // it should be killed.\n      if (parent.namespaceURI === HTML_NAMESPACE) {\n        return tagName === 'math';\n      }\n      // The only way to switch from SVG to MathML is via\n      // <math> and HTML integration points\n      if (parent.namespaceURI === SVG_NAMESPACE) {\n        return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n      }\n      // We only allow elements that are defined in MathML\n      // spec. All others are disallowed in MathML namespace.\n      return Boolean(ALL_MATHML_TAGS[tagName]);\n    }\n    if (element.namespaceURI === HTML_NAMESPACE) {\n      // The only way to switch from SVG to HTML is via\n      // HTML integration points, and from MathML to HTML\n      // is via MathML text integration points\n      if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\n        return false;\n      }\n      if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\n        return false;\n      }\n      // We disallow tags that are specific for MathML\n      // or SVG and should never appear in HTML namespace\n      return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);\n    }\n    // For XHTML and XML documents that support custom namespaces\n    if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {\n      return true;\n    }\n    // The code should never reach this place (this means\n    // that the element somehow got namespace that is not\n    // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n    // Return false just in case.\n    return false;\n  };\n  /**\n   * _forceRemove\n   *\n   * @param node a DOM node\n   */\n  const _forceRemove = function _forceRemove(node) {\n    arrayPush(DOMPurify.removed, {\n      element: node\n    });\n    try {\n      // eslint-disable-next-line unicorn/prefer-dom-node-remove\n      getParentNode(node).removeChild(node);\n    } catch (_) {\n      remove(node);\n    }\n  };\n  /**\n   * _removeAttribute\n   *\n   * @param name an Attribute name\n   * @param element a DOM node\n   */\n  const _removeAttribute = function _removeAttribute(name, element) {\n    try {\n      arrayPush(DOMPurify.removed, {\n        attribute: element.getAttributeNode(name),\n        from: element\n      });\n    } catch (_) {\n      arrayPush(DOMPurify.removed, {\n        attribute: null,\n        from: element\n      });\n    }\n    element.removeAttribute(name);\n    // We void attribute values for unremovable \"is\" attributes\n    if (name === 'is') {\n      if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n        try {\n          _forceRemove(element);\n        } catch (_) {}\n      } else {\n        try {\n          element.setAttribute(name, '');\n        } catch (_) {}\n      }\n    }\n  };\n  /**\n   * _initDocument\n   *\n   * @param dirty - a string of dirty markup\n   * @return a DOM, filled with the dirty markup\n   */\n  const _initDocument = function _initDocument(dirty) {\n    /* Create a HTML document */\n    let doc = null;\n    let leadingWhitespace = null;\n    if (FORCE_BODY) {\n      dirty = '<remove></remove>' + dirty;\n    } else {\n      /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n      const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n      leadingWhitespace = matches && matches[0];\n    }\n    if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {\n      // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n      dirty = '<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>' + dirty + '</body></html>';\n    }\n    const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\n    /*\n     * Use the DOMParser API by default, fallback later if needs be\n     * DOMParser not work for svg when has multiple root element.\n     */\n    if (NAMESPACE === HTML_NAMESPACE) {\n      try {\n        doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n      } catch (_) {}\n    }\n    /* Use createHTMLDocument in case DOMParser is not available */\n    if (!doc || !doc.documentElement) {\n      doc = implementation.createDocument(NAMESPACE, 'template', null);\n      try {\n        doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;\n      } catch (_) {\n        // Syntax error if dirtyPayload is invalid xml\n      }\n    }\n    const body = doc.body || doc.documentElement;\n    if (dirty && leadingWhitespace) {\n      body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\n    }\n    /* Work on whole document or just its body */\n    if (NAMESPACE === HTML_NAMESPACE) {\n      return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n    }\n    return WHOLE_DOCUMENT ? doc.documentElement : body;\n  };\n  /**\n   * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n   *\n   * @param root The root element or node to start traversing on.\n   * @return The created NodeIterator\n   */\n  const _createNodeIterator = function _createNodeIterator(root) {\n    return createNodeIterator.call(root.ownerDocument || root, root,\n    // eslint-disable-next-line no-bitwise\n    NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);\n  };\n  /**\n   * _isClobbered\n   *\n   * @param element element to check for clobbering attacks\n   * @return true if clobbered, false if safe\n   */\n  const _isClobbered = function _isClobbered(element) {\n    return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function');\n  };\n  /**\n   * Checks whether the given object is a DOM node.\n   *\n   * @param value object to check whether it's a DOM node\n   * @return true is object is a DOM node\n   */\n  const _isNode = function _isNode(value) {\n    return typeof Node === 'function' && value instanceof Node;\n  };\n  function _executeHooks(hooks, currentNode, data) {\n    arrayForEach(hooks, hook => {\n      hook.call(DOMPurify, currentNode, data, CONFIG);\n    });\n  }\n  /**\n   * _sanitizeElements\n   *\n   * @protect nodeName\n   * @protect textContent\n   * @protect removeChild\n   * @param currentNode to check for permission to exist\n   * @return true if node was killed, false if left alive\n   */\n  const _sanitizeElements = function _sanitizeElements(currentNode) {\n    let content = null;\n    /* Execute a hook if present */\n    _executeHooks(hooks.beforeSanitizeElements, currentNode, null);\n    /* Check if element is clobbered or can clobber */\n    if (_isClobbered(currentNode)) {\n      _forceRemove(currentNode);\n      return true;\n    }\n    /* Now let's check the element's type and name */\n    const tagName = transformCaseFunc(currentNode.nodeName);\n    /* Execute a hook if present */\n    _executeHooks(hooks.uponSanitizeElement, currentNode, {\n      tagName,\n      allowedTags: ALLOWED_TAGS\n    });\n    /* Detect mXSS attempts abusing namespace confusion */\n    if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\\w!]/g, currentNode.textContent)) {\n      _forceRemove(currentNode);\n      return true;\n    }\n    /* Remove any occurrence of processing instructions */\n    if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {\n      _forceRemove(currentNode);\n      return true;\n    }\n    /* Remove any kind of possibly harmful comments */\n    if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\\w]/g, currentNode.data)) {\n      _forceRemove(currentNode);\n      return true;\n    }\n    /* Remove element if anything forbids its presence */\n    if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n      /* Check if we have a custom element to handle */\n      if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n        if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {\n          return false;\n        }\n        if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {\n          return false;\n        }\n      }\n      /* Keep content except for bad-listed elements */\n      if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n        const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n        const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n        if (childNodes && parentNode) {\n          const childCount = childNodes.length;\n          for (let i = childCount - 1; i >= 0; --i) {\n            const childClone = cloneNode(childNodes[i], true);\n            childClone.__removalCount = (currentNode.__removalCount || 0) + 1;\n            parentNode.insertBefore(childClone, getNextSibling(currentNode));\n          }\n        }\n      }\n      _forceRemove(currentNode);\n      return true;\n    }\n    /* Check whether element has a valid namespace */\n    if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n      _forceRemove(currentNode);\n      return true;\n    }\n    /* Make sure that older browsers don't get fallback-tag mXSS */\n    if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)) {\n      _forceRemove(currentNode);\n      return true;\n    }\n    /* Sanitize element content to be template-safe */\n    if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n      /* Get the element's text content */\n      content = currentNode.textContent;\n      arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n        content = stringReplace(content, expr, ' ');\n      });\n      if (currentNode.textContent !== content) {\n        arrayPush(DOMPurify.removed, {\n          element: currentNode.cloneNode()\n        });\n        currentNode.textContent = content;\n      }\n    }\n    /* Execute a hook if present */\n    _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n    return false;\n  };\n  /**\n   * _isValidAttribute\n   *\n   * @param lcTag Lowercase tag name of containing element.\n   * @param lcName Lowercase attribute name.\n   * @param value Attribute value.\n   * @return Returns true if `value` is valid, otherwise false.\n   */\n  // eslint-disable-next-line complexity\n  const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {\n    /* Make sure attribute cannot clobber */\n    if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {\n      return false;\n    }\n    /* Allow valid data-* attributes: At least one character after \"-\"\n        (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n        XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n        We don't need to check the value; it's always URI safe. */\n    if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n      if (\n      // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n      // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n      // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n      _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) ||\n      // Alternative, second condition checks if it's an `is`-attribute, AND\n      // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n      lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {\n        return false;\n      }\n      /* Check value is safe. First, is attr inert? If so, is safe */\n    } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {\n      return false;\n    } else ;\n    return true;\n  };\n  /**\n   * _isBasicCustomElement\n   * checks if at least one dash is included in tagName, and it's not the first char\n   * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n   *\n   * @param tagName name of the tag of the node to sanitize\n   * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n   */\n  const _isBasicCustomElement = function _isBasicCustomElement(tagName) {\n    return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);\n  };\n  /**\n   * _sanitizeAttributes\n   *\n   * @protect attributes\n   * @protect nodeName\n   * @protect removeAttribute\n   * @protect setAttribute\n   *\n   * @param currentNode to sanitize\n   */\n  const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {\n    /* Execute a hook if present */\n    _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);\n    const {\n      attributes\n    } = currentNode;\n    /* Check if we have attributes; if not we might have a text node */\n    if (!attributes || _isClobbered(currentNode)) {\n      return;\n    }\n    const hookEvent = {\n      attrName: '',\n      attrValue: '',\n      keepAttr: true,\n      allowedAttributes: ALLOWED_ATTR,\n      forceKeepAttr: undefined\n    };\n    let l = attributes.length;\n    /* Go backwards over all attributes; safely remove bad ones */\n    while (l--) {\n      const attr = attributes[l];\n      const {\n        name,\n        namespaceURI,\n        value: attrValue\n      } = attr;\n      const lcName = transformCaseFunc(name);\n      const initValue = attrValue;\n      let value = name === 'value' ? initValue : stringTrim(initValue);\n      /* Execute a hook if present */\n      hookEvent.attrName = lcName;\n      hookEvent.attrValue = value;\n      hookEvent.keepAttr = true;\n      hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n      _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);\n      value = hookEvent.attrValue;\n      /* Full DOM Clobbering protection via namespace isolation,\n       * Prefix id and name attributes with `user-content-`\n       */\n      if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n        // Remove the attribute with this value\n        _removeAttribute(name, currentNode);\n        // Prefix the value and later re-create the attribute with the sanitized value\n        value = SANITIZE_NAMED_PROPS_PREFIX + value;\n      }\n      /* Work around a security issue with comments inside attributes */\n      if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\\/(style|title|textarea)/i, value)) {\n        _removeAttribute(name, currentNode);\n        continue;\n      }\n      /* Make sure we cannot easily use animated hrefs, even if animations are allowed */\n      if (lcName === 'attributename' && stringMatch(value, 'href')) {\n        _removeAttribute(name, currentNode);\n        continue;\n      }\n      /* Did the hooks approve of the attribute? */\n      if (hookEvent.forceKeepAttr) {\n        continue;\n      }\n      /* Did the hooks approve of the attribute? */\n      if (!hookEvent.keepAttr) {\n        _removeAttribute(name, currentNode);\n        continue;\n      }\n      /* Work around a security issue in jQuery 3.0 */\n      if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n        _removeAttribute(name, currentNode);\n        continue;\n      }\n      /* Sanitize attribute content to be template-safe */\n      if (SAFE_FOR_TEMPLATES) {\n        arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n          value = stringReplace(value, expr, ' ');\n        });\n      }\n      /* Is `value` valid for this attribute? */\n      const lcTag = transformCaseFunc(currentNode.nodeName);\n      if (!_isValidAttribute(lcTag, lcName, value)) {\n        _removeAttribute(name, currentNode);\n        continue;\n      }\n      /* Handle attributes that require Trusted Types */\n      if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {\n        if (namespaceURI) ; else {\n          switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n            case 'TrustedHTML':\n              {\n                value = trustedTypesPolicy.createHTML(value);\n                break;\n              }\n            case 'TrustedScriptURL':\n              {\n                value = trustedTypesPolicy.createScriptURL(value);\n                break;\n              }\n          }\n        }\n      }\n      /* Handle invalid data-* attribute set by try-catching it */\n      if (value !== initValue) {\n        try {\n          if (namespaceURI) {\n            currentNode.setAttributeNS(namespaceURI, name, value);\n          } else {\n            /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n            currentNode.setAttribute(name, value);\n          }\n          if (_isClobbered(currentNode)) {\n            _forceRemove(currentNode);\n          } else {\n            arrayPop(DOMPurify.removed);\n          }\n        } catch (_) {\n          _removeAttribute(name, currentNode);\n        }\n      }\n    }\n    /* Execute a hook if present */\n    _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);\n  };\n  /**\n   * _sanitizeShadowDOM\n   *\n   * @param fragment to iterate over recursively\n   */\n  const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {\n    let shadowNode = null;\n    const shadowIterator = _createNodeIterator(fragment);\n    /* Execute a hook if present */\n    _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);\n    while (shadowNode = shadowIterator.nextNode()) {\n      /* Execute a hook if present */\n      _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);\n      /* Sanitize tags and elements */\n      _sanitizeElements(shadowNode);\n      /* Check attributes next */\n      _sanitizeAttributes(shadowNode);\n      /* Deep shadow DOM detected */\n      if (shadowNode.content instanceof DocumentFragment) {\n        _sanitizeShadowDOM(shadowNode.content);\n      }\n    }\n    /* Execute a hook if present */\n    _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);\n  };\n  // eslint-disable-next-line complexity\n  DOMPurify.sanitize = function (dirty) {\n    let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    let body = null;\n    let importedNode = null;\n    let currentNode = null;\n    let returnNode = null;\n    /* Make sure we have a string to sanitize.\n      DO NOT return early, as this will return the wrong type if\n      the user has requested a DOM object rather than a string */\n    IS_EMPTY_INPUT = !dirty;\n    if (IS_EMPTY_INPUT) {\n      dirty = '<!-->';\n    }\n    /* Stringify, in case dirty is an object */\n    if (typeof dirty !== 'string' && !_isNode(dirty)) {\n      if (typeof dirty.toString === 'function') {\n        dirty = dirty.toString();\n        if (typeof dirty !== 'string') {\n          throw typeErrorCreate('dirty is not a string, aborting');\n        }\n      } else {\n        throw typeErrorCreate('toString is not a function');\n      }\n    }\n    /* Return dirty HTML if DOMPurify cannot run */\n    if (!DOMPurify.isSupported) {\n      return dirty;\n    }\n    /* Assign config vars */\n    if (!SET_CONFIG) {\n      _parseConfig(cfg);\n    }\n    /* Clean up removed elements */\n    DOMPurify.removed = [];\n    /* Check if dirty is correctly typed for IN_PLACE */\n    if (typeof dirty === 'string') {\n      IN_PLACE = false;\n    }\n    if (IN_PLACE) {\n      /* Do some early pre-sanitization to avoid unsafe root nodes */\n      if (dirty.nodeName) {\n        const tagName = transformCaseFunc(dirty.nodeName);\n        if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n          throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');\n        }\n      }\n    } else if (dirty instanceof Node) {\n      /* If dirty is a DOM element, append to an empty document to avoid\n         elements being stripped by the parser */\n      body = _initDocument('<!---->');\n      importedNode = body.ownerDocument.importNode(dirty, true);\n      if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {\n        /* Node is already a body, use as is */\n        body = importedNode;\n      } else if (importedNode.nodeName === 'HTML') {\n        body = importedNode;\n      } else {\n        // eslint-disable-next-line unicorn/prefer-dom-node-append\n        body.appendChild(importedNode);\n      }\n    } else {\n      /* Exit directly if we have nothing to do */\n      if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&\n      // eslint-disable-next-line unicorn/prefer-includes\n      dirty.indexOf('<') === -1) {\n        return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;\n      }\n      /* Initialize the document to work on */\n      body = _initDocument(dirty);\n      /* Check we have a DOM node from the data */\n      if (!body) {\n        return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n      }\n    }\n    /* Remove first element node (ours) if FORCE_BODY is set */\n    if (body && FORCE_BODY) {\n      _forceRemove(body.firstChild);\n    }\n    /* Get node iterator */\n    const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);\n    /* Now start iterating over the created document */\n    while (currentNode = nodeIterator.nextNode()) {\n      /* Sanitize tags and elements */\n      _sanitizeElements(currentNode);\n      /* Check attributes next */\n      _sanitizeAttributes(currentNode);\n      /* Shadow DOM detected, sanitize it */\n      if (currentNode.content instanceof DocumentFragment) {\n        _sanitizeShadowDOM(currentNode.content);\n      }\n    }\n    /* If we sanitized `dirty` in-place, return it. */\n    if (IN_PLACE) {\n      return dirty;\n    }\n    /* Return sanitized string or DOM */\n    if (RETURN_DOM) {\n      if (RETURN_DOM_FRAGMENT) {\n        returnNode = createDocumentFragment.call(body.ownerDocument);\n        while (body.firstChild) {\n          // eslint-disable-next-line unicorn/prefer-dom-node-append\n          returnNode.appendChild(body.firstChild);\n        }\n      } else {\n        returnNode = body;\n      }\n      if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n        /*\n          AdoptNode() is not used because internal state is not reset\n          (e.g. the past names map of a HTMLFormElement), this is safe\n          in theory but we would rather not risk another attack vector.\n          The state that is cloned by importNode() is explicitly defined\n          by the specs.\n        */\n        returnNode = importNode.call(originalDocument, returnNode, true);\n      }\n      return returnNode;\n    }\n    let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n    /* Serialize doctype if allowed */\n    if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {\n      serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\\n' + serializedHTML;\n    }\n    /* Sanitize final string template-safe */\n    if (SAFE_FOR_TEMPLATES) {\n      arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n        serializedHTML = stringReplace(serializedHTML, expr, ' ');\n      });\n    }\n    return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;\n  };\n  DOMPurify.setConfig = function () {\n    let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n    _parseConfig(cfg);\n    SET_CONFIG = true;\n  };\n  DOMPurify.clearConfig = function () {\n    CONFIG = null;\n    SET_CONFIG = false;\n  };\n  DOMPurify.isValidAttribute = function (tag, attr, value) {\n    /* Initialize shared config vars if necessary. */\n    if (!CONFIG) {\n      _parseConfig({});\n    }\n    const lcTag = transformCaseFunc(tag);\n    const lcName = transformCaseFunc(attr);\n    return _isValidAttribute(lcTag, lcName, value);\n  };\n  DOMPurify.addHook = function (entryPoint, hookFunction) {\n    if (typeof hookFunction !== 'function') {\n      return;\n    }\n    arrayPush(hooks[entryPoint], hookFunction);\n  };\n  DOMPurify.removeHook = function (entryPoint, hookFunction) {\n    if (hookFunction !== undefined) {\n      const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);\n      return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];\n    }\n    return arrayPop(hooks[entryPoint]);\n  };\n  DOMPurify.removeHooks = function (entryPoint) {\n    hooks[entryPoint] = [];\n  };\n  DOMPurify.removeAllHooks = function () {\n    hooks = _createHooksMap();\n  };\n  return DOMPurify;\n}\nvar purify = createDOMPurify();\n\nexport { purify as default };\n//# sourceMappingURL=purify.es.mjs.map\n","// Function to sanitize HTML and return it as unsafeHTML for Lit rendering\n\nimport { unsafeHTML } from \"lit-html/directives/unsafe-html.js\"\nimport DOMPurify from \"dompurify\"\n\n// It allow to dynamically create HTML elements with a specific tag name and be sure it's safe\nexport const sanitizeHtml = (html: string) => unsafeHTML(DOMPurify.sanitize(html))\n","export default class Diff {\n    diff(oldStr, newStr, \n    // Type below is not accurate/complete - see above for full possibilities - but it compiles\n    options = {}) {\n        let callback;\n        if (typeof options === 'function') {\n            callback = options;\n            options = {};\n        }\n        else if ('callback' in options) {\n            callback = options.callback;\n        }\n        // Allow subclasses to massage the input prior to running\n        const oldString = this.castInput(oldStr, options);\n        const newString = this.castInput(newStr, options);\n        const oldTokens = this.removeEmpty(this.tokenize(oldString, options));\n        const newTokens = this.removeEmpty(this.tokenize(newString, options));\n        return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);\n    }\n    diffWithOptionsObj(oldTokens, newTokens, options, callback) {\n        var _a;\n        const done = (value) => {\n            value = this.postProcess(value, options);\n            if (callback) {\n                setTimeout(function () { callback(value); }, 0);\n                return undefined;\n            }\n            else {\n                return value;\n            }\n        };\n        const newLen = newTokens.length, oldLen = oldTokens.length;\n        let editLength = 1;\n        let maxEditLength = newLen + oldLen;\n        if (options.maxEditLength != null) {\n            maxEditLength = Math.min(maxEditLength, options.maxEditLength);\n        }\n        const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity;\n        const abortAfterTimestamp = Date.now() + maxExecutionTime;\n        const bestPath = [{ oldPos: -1, lastComponent: undefined }];\n        // Seed editLength = 0, i.e. the content starts with the same values\n        let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);\n        if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n            // Identity per the equality and tokenizer\n            return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));\n        }\n        // Once we hit the right edge of the edit graph on some diagonal k, we can\n        // definitely reach the end of the edit graph in no more than k edits, so\n        // there's no point in considering any moves to diagonal k+1 any more (from\n        // which we're guaranteed to need at least k+1 more edits).\n        // Similarly, once we've reached the bottom of the edit graph, there's no\n        // point considering moves to lower diagonals.\n        // We record this fact by setting minDiagonalToConsider and\n        // maxDiagonalToConsider to some finite value once we've hit the edge of\n        // the edit graph.\n        // This optimization is not faithful to the original algorithm presented in\n        // Myers's paper, which instead pointlessly extends D-paths off the end of\n        // the edit graph - see page 7 of Myers's paper which notes this point\n        // explicitly and illustrates it with a diagram. This has major performance\n        // implications for some common scenarios. For instance, to compute a diff\n        // where the new text simply appends d characters on the end of the\n        // original text of length n, the true Myers algorithm will take O(n+d^2)\n        // time while this optimization needs only O(n+d) time.\n        let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;\n        // Main worker method. checks all permutations of a given edit length for acceptance.\n        const execEditLength = () => {\n            for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {\n                let basePath;\n                const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];\n                if (removePath) {\n                    // No one else is going to attempt to use this value, clear it\n                    // @ts-expect-error - perf optimisation. This type-violating value will never be read.\n                    bestPath[diagonalPath - 1] = undefined;\n                }\n                let canAdd = false;\n                if (addPath) {\n                    // what newPos will be after we do an insertion:\n                    const addPathNewPos = addPath.oldPos - diagonalPath;\n                    canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;\n                }\n                const canRemove = removePath && removePath.oldPos + 1 < oldLen;\n                if (!canAdd && !canRemove) {\n                    // If this path is a terminal then prune\n                    // @ts-expect-error - perf optimisation. This type-violating value will never be read.\n                    bestPath[diagonalPath] = undefined;\n                    continue;\n                }\n                // Select the diagonal that we want to branch from. We select the prior\n                // path whose position in the old string is the farthest from the origin\n                // and does not pass the bounds of the diff graph\n                if (!canRemove || (canAdd && removePath.oldPos < addPath.oldPos)) {\n                    basePath = this.addToPath(addPath, true, false, 0, options);\n                }\n                else {\n                    basePath = this.addToPath(removePath, false, true, 1, options);\n                }\n                newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);\n                if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n                    // If we have hit the end of both strings, then we are done\n                    return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;\n                }\n                else {\n                    bestPath[diagonalPath] = basePath;\n                    if (basePath.oldPos + 1 >= oldLen) {\n                        maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);\n                    }\n                    if (newPos + 1 >= newLen) {\n                        minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);\n                    }\n                }\n            }\n            editLength++;\n        };\n        // Performs the length of edit iteration. Is a bit fugly as this has to support the\n        // sync and async mode which is never fun. Loops over execEditLength until a value\n        // is produced, or until the edit length exceeds options.maxEditLength (if given),\n        // in which case it will return undefined.\n        if (callback) {\n            (function exec() {\n                setTimeout(function () {\n                    if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {\n                        return callback(undefined);\n                    }\n                    if (!execEditLength()) {\n                        exec();\n                    }\n                }, 0);\n            }());\n        }\n        else {\n            while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {\n                const ret = execEditLength();\n                if (ret) {\n                    return ret;\n                }\n            }\n        }\n    }\n    addToPath(path, added, removed, oldPosInc, options) {\n        const last = path.lastComponent;\n        if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {\n            return {\n                oldPos: path.oldPos + oldPosInc,\n                lastComponent: { count: last.count + 1, added: added, removed: removed, previousComponent: last.previousComponent }\n            };\n        }\n        else {\n            return {\n                oldPos: path.oldPos + oldPosInc,\n                lastComponent: { count: 1, added: added, removed: removed, previousComponent: last }\n            };\n        }\n    }\n    extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {\n        const newLen = newTokens.length, oldLen = oldTokens.length;\n        let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;\n        while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {\n            newPos++;\n            oldPos++;\n            commonCount++;\n            if (options.oneChangePerToken) {\n                basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };\n            }\n        }\n        if (commonCount && !options.oneChangePerToken) {\n            basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };\n        }\n        basePath.oldPos = oldPos;\n        return newPos;\n    }\n    equals(left, right, options) {\n        if (options.comparator) {\n            return options.comparator(left, right);\n        }\n        else {\n            return left === right\n                || (!!options.ignoreCase && left.toLowerCase() === right.toLowerCase());\n        }\n    }\n    removeEmpty(array) {\n        const ret = [];\n        for (let i = 0; i < array.length; i++) {\n            if (array[i]) {\n                ret.push(array[i]);\n            }\n        }\n        return ret;\n    }\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    castInput(value, options) {\n        return value;\n    }\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    tokenize(value, options) {\n        return Array.from(value);\n    }\n    join(chars) {\n        // Assumes ValueT is string, which is the case for most subclasses.\n        // When it's false, e.g. in diffArrays, this method needs to be overridden (e.g. with a no-op)\n        // Yes, the casts are verbose and ugly, because this pattern - of having the base class SORT OF\n        // assume tokens and values are strings, but not completely - is weird and janky.\n        return chars.join('');\n    }\n    postProcess(changeObjects, \n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    options) {\n        return changeObjects;\n    }\n    get useLongestToken() {\n        return false;\n    }\n    buildValues(lastComponent, newTokens, oldTokens) {\n        // First we convert our linked list of components in reverse order to an\n        // array in the right order:\n        const components = [];\n        let nextComponent;\n        while (lastComponent) {\n            components.push(lastComponent);\n            nextComponent = lastComponent.previousComponent;\n            delete lastComponent.previousComponent;\n            lastComponent = nextComponent;\n        }\n        components.reverse();\n        const componentLen = components.length;\n        let componentPos = 0, newPos = 0, oldPos = 0;\n        for (; componentPos < componentLen; componentPos++) {\n            const component = components[componentPos];\n            if (!component.removed) {\n                if (!component.added && this.useLongestToken) {\n                    let value = newTokens.slice(newPos, newPos + component.count);\n                    value = value.map(function (value, i) {\n                        const oldValue = oldTokens[oldPos + i];\n                        return oldValue.length > value.length ? oldValue : value;\n                    });\n                    component.value = this.join(value);\n                }\n                else {\n                    component.value = this.join(newTokens.slice(newPos, newPos + component.count));\n                }\n                newPos += component.count;\n                // Common case\n                if (!component.added) {\n                    oldPos += component.count;\n                }\n            }\n            else {\n                component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));\n                oldPos += component.count;\n            }\n        }\n        return components;\n    }\n}\n","import Diff from './base.js';\nimport { longestCommonPrefix, longestCommonSuffix, replacePrefix, replaceSuffix, removePrefix, removeSuffix, maximumOverlap, leadingWs, trailingWs } from '../util/string.js';\n// Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode\n//\n// Chars/ranges counted as \"word\" characters by this regex are as follows:\n//\n// + U+00AD  Soft hyphen\n// + 00C0–00FF (letters with diacritics from the Latin-1 Supplement), except:\n//   - U+00D7  × Multiplication sign\n//   - U+00F7  ÷ Division sign\n// + Latin Extended-A, 0100–017F\n// + Latin Extended-B, 0180–024F\n// + IPA Extensions, 0250–02AF\n// + Spacing Modifier Letters, 02B0–02FF, except:\n//   - U+02C7  ˇ &#711;  Caron\n//   - U+02D8  ˘ &#728;  Breve\n//   - U+02D9  ˙ &#729;  Dot Above\n//   - U+02DA  ˚ &#730;  Ring Above\n//   - U+02DB  ˛ &#731;  Ogonek\n//   - U+02DC  ˜ &#732;  Small Tilde\n//   - U+02DD  ˝ &#733;  Double Acute Accent\n// + Latin Extended Additional, 1E00–1EFF\nconst extendedWordChars = 'a-zA-Z0-9_\\\\u{AD}\\\\u{C0}-\\\\u{D6}\\\\u{D8}-\\\\u{F6}\\\\u{F8}-\\\\u{2C6}\\\\u{2C8}-\\\\u{2D7}\\\\u{2DE}-\\\\u{2FF}\\\\u{1E00}-\\\\u{1EFF}';\n// Each token is one of the following:\n// - A punctuation mark plus the surrounding whitespace\n// - A word plus the surrounding whitespace\n// - Pure whitespace (but only in the special case where the entire text\n//   is just whitespace)\n//\n// We have to include surrounding whitespace in the tokens because the two\n// alternative approaches produce horribly broken results:\n// * If we just discard the whitespace, we can't fully reproduce the original\n//   text from the sequence of tokens and any attempt to render the diff will\n//   get the whitespace wrong.\n// * If we have separate tokens for whitespace, then in a typical text every\n//   second token will be a single space character. But this often results in\n//   the optimal diff between two texts being a perverse one that preserves\n//   the spaces between words but deletes and reinserts actual common words.\n//   See https://github.com/kpdecker/jsdiff/issues/160#issuecomment-1866099640\n//   for an example.\n//\n// Keeping the surrounding whitespace of course has implications for .equals\n// and .join, not just .tokenize.\n// This regex does NOT fully implement the tokenization rules described above.\n// Instead, it gives runs of whitespace their own \"token\". The tokenize method\n// then handles stitching whitespace tokens onto adjacent word or punctuation\n// tokens.\nconst tokenizeIncludingWhitespace = new RegExp(`[${extendedWordChars}]+|\\\\s+|[^${extendedWordChars}]`, 'ug');\nclass WordDiff extends Diff {\n    equals(left, right, options) {\n        if (options.ignoreCase) {\n            left = left.toLowerCase();\n            right = right.toLowerCase();\n        }\n        return left.trim() === right.trim();\n    }\n    tokenize(value, options = {}) {\n        let parts;\n        if (options.intlSegmenter) {\n            const segmenter = options.intlSegmenter;\n            if (segmenter.resolvedOptions().granularity != 'word') {\n                throw new Error('The segmenter passed must have a granularity of \"word\"');\n            }\n            // We want `parts` to be an array whose elements alternate between being\n            // pure whitespace and being pure non-whitespace. This is ALMOST what the\n            // segments returned by a word-based Intl.Segmenter already look like,\n            // and therefore we can ALMOST get what we want by simply doing...\n            //     parts = Array.from(segmenter.segment(value), segment => segment.segment);\n            // ... but not QUITE, because there's of one annoying special case: every\n            // newline character gets its own segment, instead of sharing a segment\n            // with other surrounding whitespace. We therefore need to manually merge\n            // consecutive segments of whitespace into a single part:\n            parts = [];\n            for (const segmentObj of Array.from(segmenter.segment(value))) {\n                const segment = segmentObj.segment;\n                if (parts.length && (/\\s/).test(parts[parts.length - 1]) && (/\\s/).test(segment)) {\n                    parts[parts.length - 1] += segment;\n                }\n                else {\n                    parts.push(segment);\n                }\n            }\n        }\n        else {\n            parts = value.match(tokenizeIncludingWhitespace) || [];\n        }\n        const tokens = [];\n        let prevPart = null;\n        parts.forEach(part => {\n            if ((/\\s/).test(part)) {\n                if (prevPart == null) {\n                    tokens.push(part);\n                }\n                else {\n                    tokens.push(tokens.pop() + part);\n                }\n            }\n            else if (prevPart != null && (/\\s/).test(prevPart)) {\n                if (tokens[tokens.length - 1] == prevPart) {\n                    tokens.push(tokens.pop() + part);\n                }\n                else {\n                    tokens.push(prevPart + part);\n                }\n            }\n            else {\n                tokens.push(part);\n            }\n            prevPart = part;\n        });\n        return tokens;\n    }\n    join(tokens) {\n        // Tokens being joined here will always have appeared consecutively in the\n        // same text, so we can simply strip off the leading whitespace from all the\n        // tokens except the first (and except any whitespace-only tokens - but such\n        // a token will always be the first and only token anyway) and then join them\n        // and the whitespace around words and punctuation will end up correct.\n        return tokens.map((token, i) => {\n            if (i == 0) {\n                return token;\n            }\n            else {\n                return token.replace((/^\\s+/), '');\n            }\n        }).join('');\n    }\n    postProcess(changes, options) {\n        if (!changes || options.oneChangePerToken) {\n            return changes;\n        }\n        let lastKeep = null;\n        // Change objects representing any insertion or deletion since the last\n        // \"keep\" change object. There can be at most one of each.\n        let insertion = null;\n        let deletion = null;\n        changes.forEach(change => {\n            if (change.added) {\n                insertion = change;\n            }\n            else if (change.removed) {\n                deletion = change;\n            }\n            else {\n                if (insertion || deletion) { // May be false at start of text\n                    dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, change);\n                }\n                lastKeep = change;\n                insertion = null;\n                deletion = null;\n            }\n        });\n        if (insertion || deletion) {\n            dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, null);\n        }\n        return changes;\n    }\n}\nexport const wordDiff = new WordDiff();\nexport function diffWords(oldStr, newStr, options) {\n    // This option has never been documented and never will be (it's clearer to\n    // just call `diffWordsWithSpace` directly if you need that behavior), but\n    // has existed in jsdiff for a long time, so we retain support for it here\n    // for the sake of backwards compatibility.\n    if ((options === null || options === void 0 ? void 0 : options.ignoreWhitespace) != null && !options.ignoreWhitespace) {\n        return diffWordsWithSpace(oldStr, newStr, options);\n    }\n    return wordDiff.diff(oldStr, newStr, options);\n}\nfunction dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep) {\n    // Before returning, we tidy up the leading and trailing whitespace of the\n    // change objects to eliminate cases where trailing whitespace in one object\n    // is repeated as leading whitespace in the next.\n    // Below are examples of the outcomes we want here to explain the code.\n    // I=insert, K=keep, D=delete\n    // 1. diffing 'foo bar baz' vs 'foo baz'\n    //    Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz'\n    //    After cleanup, we want:   K:'foo ' D:'bar ' K:'baz'\n    //\n    // 2. Diffing 'foo bar baz' vs 'foo qux baz'\n    //    Prior to cleanup, we have K:'foo ' D:' bar ' I:' qux ' K:' baz'\n    //    After cleanup, we want K:'foo ' D:'bar' I:'qux' K:' baz'\n    //\n    // 3. Diffing 'foo\\nbar baz' vs 'foo baz'\n    //    Prior to cleanup, we have K:'foo ' D:'\\nbar ' K:' baz'\n    //    After cleanup, we want K'foo' D:'\\nbar' K:' baz'\n    //\n    // 4. Diffing 'foo baz' vs 'foo\\nbar baz'\n    //    Prior to cleanup, we have K:'foo\\n' I:'\\nbar ' K:' baz'\n    //    After cleanup, we ideally want K'foo' I:'\\nbar' K:' baz'\n    //    but don't actually manage this currently (the pre-cleanup change\n    //    objects don't contain enough information to make it possible).\n    //\n    // 5. Diffing 'foo   bar baz' vs 'foo  baz'\n    //    Prior to cleanup, we have K:'foo  ' D:'   bar ' K:'  baz'\n    //    After cleanup, we want K:'foo  ' D:' bar ' K:'baz'\n    //\n    // Our handling is unavoidably imperfect in the case where there's a single\n    // indel between keeps and the whitespace has changed. For instance, consider\n    // diffing 'foo\\tbar\\nbaz' vs 'foo baz'. Unless we create an extra change\n    // object to represent the insertion of the space character (which isn't even\n    // a token), we have no way to avoid losing information about the texts'\n    // original whitespace in the result we return. Still, we do our best to\n    // output something that will look sensible if we e.g. print it with\n    // insertions in green and deletions in red.\n    // Between two \"keep\" change objects (or before the first or after the last\n    // change object), we can have either:\n    // * A \"delete\" followed by an \"insert\"\n    // * Just an \"insert\"\n    // * Just a \"delete\"\n    // We handle the three cases separately.\n    if (deletion && insertion) {\n        const oldWsPrefix = leadingWs(deletion.value);\n        const oldWsSuffix = trailingWs(deletion.value);\n        const newWsPrefix = leadingWs(insertion.value);\n        const newWsSuffix = trailingWs(insertion.value);\n        if (startKeep) {\n            const commonWsPrefix = longestCommonPrefix(oldWsPrefix, newWsPrefix);\n            startKeep.value = replaceSuffix(startKeep.value, newWsPrefix, commonWsPrefix);\n            deletion.value = removePrefix(deletion.value, commonWsPrefix);\n            insertion.value = removePrefix(insertion.value, commonWsPrefix);\n        }\n        if (endKeep) {\n            const commonWsSuffix = longestCommonSuffix(oldWsSuffix, newWsSuffix);\n            endKeep.value = replacePrefix(endKeep.value, newWsSuffix, commonWsSuffix);\n            deletion.value = removeSuffix(deletion.value, commonWsSuffix);\n            insertion.value = removeSuffix(insertion.value, commonWsSuffix);\n        }\n    }\n    else if (insertion) {\n        // The whitespaces all reflect what was in the new text rather than\n        // the old, so we essentially have no information about whitespace\n        // insertion or deletion. We just want to dedupe the whitespace.\n        // We do that by having each change object keep its trailing\n        // whitespace and deleting duplicate leading whitespace where\n        // present.\n        if (startKeep) {\n            const ws = leadingWs(insertion.value);\n            insertion.value = insertion.value.substring(ws.length);\n        }\n        if (endKeep) {\n            const ws = leadingWs(endKeep.value);\n            endKeep.value = endKeep.value.substring(ws.length);\n        }\n        // otherwise we've got a deletion and no insertion\n    }\n    else if (startKeep && endKeep) {\n        const newWsFull = leadingWs(endKeep.value), delWsStart = leadingWs(deletion.value), delWsEnd = trailingWs(deletion.value);\n        // Any whitespace that comes straight after startKeep in both the old and\n        // new texts, assign to startKeep and remove from the deletion.\n        const newWsStart = longestCommonPrefix(newWsFull, delWsStart);\n        deletion.value = removePrefix(deletion.value, newWsStart);\n        // Any whitespace that comes straight before endKeep in both the old and\n        // new texts, and hasn't already been assigned to startKeep, assign to\n        // endKeep and remove from the deletion.\n        const newWsEnd = longestCommonSuffix(removePrefix(newWsFull, newWsStart), delWsEnd);\n        deletion.value = removeSuffix(deletion.value, newWsEnd);\n        endKeep.value = replacePrefix(endKeep.value, newWsFull, newWsEnd);\n        // If there's any whitespace from the new text that HASN'T already been\n        // assigned, assign it to the start:\n        startKeep.value = replaceSuffix(startKeep.value, newWsFull, newWsFull.slice(0, newWsFull.length - newWsEnd.length));\n    }\n    else if (endKeep) {\n        // We are at the start of the text. Preserve all the whitespace on\n        // endKeep, and just remove whitespace from the end of deletion to the\n        // extent that it overlaps with the start of endKeep.\n        const endKeepWsPrefix = leadingWs(endKeep.value);\n        const deletionWsSuffix = trailingWs(deletion.value);\n        const overlap = maximumOverlap(deletionWsSuffix, endKeepWsPrefix);\n        deletion.value = removeSuffix(deletion.value, overlap);\n    }\n    else if (startKeep) {\n        // We are at the END of the text. Preserve all the whitespace on\n        // startKeep, and just remove whitespace from the start of deletion to\n        // the extent that it overlaps with the end of startKeep.\n        const startKeepWsSuffix = trailingWs(startKeep.value);\n        const deletionWsPrefix = leadingWs(deletion.value);\n        const overlap = maximumOverlap(startKeepWsSuffix, deletionWsPrefix);\n        deletion.value = removePrefix(deletion.value, overlap);\n    }\n}\nclass WordsWithSpaceDiff extends Diff {\n    tokenize(value) {\n        // Slightly different to the tokenizeIncludingWhitespace regex used above in\n        // that this one treats each individual newline as a distinct token, rather\n        // than merging them into other surrounding whitespace. This was requested\n        // in https://github.com/kpdecker/jsdiff/issues/180 &\n        //    https://github.com/kpdecker/jsdiff/issues/211\n        const regex = new RegExp(`(\\\\r?\\\\n)|[${extendedWordChars}]+|[^\\\\S\\\\n\\\\r]+|[^${extendedWordChars}]`, 'ug');\n        return value.match(regex) || [];\n    }\n}\nexport const wordsWithSpaceDiff = new WordsWithSpaceDiff();\nexport function diffWordsWithSpace(oldStr, newStr, options) {\n    return wordsWithSpaceDiff.diff(oldStr, newStr, options);\n}\n","import { LitElement } from \"lit\"\nimport { diffWordsWithSpace, type Change } from \"diff\"\nimport { state } from \"lit/decorators.js\"\nimport type { IndexedChange } from \"../types/ingredient-spellcheck\"\nimport type { Constructor } from \".\"\n/**\n * Interface for the TextCorrectorMixin.\n */\nexport interface TextDiffMixinInterface {\n  diffResult: IndexedChange[]\n  getResult(): string\n  computeDiffResult(original: string, textToCompare: string): void\n}\n\n/**\n * Mixin that adds text diff functionality to a LitElement.\n */\nexport const TextDiffMixin = <T extends Constructor<LitElement>>(\n  superClass: T\n): Constructor<TextDiffMixinInterface> & T => {\n  class TextCorrectorMixinClass extends superClass {\n    /**\n     * Gets the result of the diff.\n     * @returns {string} The result of the diff.\n     */\n    getResult() {\n      return this.diffResult.map((change) => change.value).join(\"\")\n    }\n\n    /**\n     * The result of the diff between the original and corrected text.\n     * @type {IndexedChange[]}\n     */\n    @state()\n    diffResult: IndexedChange[] = []\n\n    computeDiffResult(value: string, textToCompare: string) {\n      this.diffResult = diffWordsWithSpace(value, textToCompare).map(\n        (part: Change, index: number) => {\n          return {\n            ...part,\n            index,\n          }\n        }\n      )\n    }\n  }\n\n  return TextCorrectorMixinClass as Constructor<TextDiffMixinInterface> & T\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { sanitizeHtml } from \"../html\"\n\n/**\n * Validates and normalizes the heading level\n * @param headingLevel - The heading level to validate\n * @returns Validated heading level string\n */\nexport function getValidHeadingLevel(headingLevel: string, defaultLevel: string = \"h3\"): string {\n  const validLevels = [\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"]\n  const level = headingLevel.toLowerCase()\n  return validLevels.includes(level) ? level : defaultLevel // Default to h3 if invalid\n}\n\n/**\n * Calculates a subordinate heading level based on the main heading level\n * @param headingLevel - The base heading level\n * @param offset - Number of levels to add (1 = one level deeper)\n * @returns A valid heading level string (h1-h6)\n */\nexport function getSubHeadingLevel(headingLevel: string, offset: number = 1): string {\n  const currentLevel = parseInt(getValidHeadingLevel(headingLevel).substring(1))\n  const newLevel = Math.min(currentLevel + offset, 6) // Ensure we don't go beyond h6\n  return `h${newLevel}`\n}\n\n/**\n * Dynamic heading renderer component\n *\n * @element heading-renderer\n */\n@customElement(\"heading-renderer\")\nexport class HeadingRenderer extends LitElement {\n  static override styles = css`\n    :host {\n      display: block;\n    }\n  `\n\n  @property({ type: String })\n  text = \"\"\n\n  @property({ type: String, attribute: \"class-name\" })\n  override className: string = \"\"\n\n  @property({ type: String, attribute: \"heading-level\" })\n  headingLevel = \"h3\"\n\n  @property({ type: Number })\n  offset = 0\n\n  override render(): TemplateResult {\n    // If offset is provided, calculate a different heading level\n    const level =\n      this.offset === 0\n        ? getValidHeadingLevel(this.headingLevel)\n        : getSubHeadingLevel(this.headingLevel, this.offset)\n\n    const classAttr = this.className ? `class=\"${this.className}\"` : \"\"\n\n    // Using unsafeHTML to dynamically create the appropriate heading element\n    const sanitizedHTML = sanitizeHtml(`<${level} ${classAttr}>${this.text}</${level}>`)\n    return html`${sanitizedHTML}`\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"heading-renderer\": HeadingRenderer\n  }\n}\n","import { html, css, type PropertyValues } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { BASE } from \"../../styles/base\"\nimport { msg } from \"@lit/localize\"\nimport \"../icons/check\"\nimport \"../icons/cross\"\nimport \"../icons/skip\"\nimport \"../icons/edit\"\nimport \"../shared/info-button\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\nimport { TEXTAREA } from \"../../styles/form\"\nimport { POPOVER } from \"../../styles/popover\"\nimport { TEXT_CORRECTOR } from \"../../styles/text-corrector\"\nimport { RELATIVE } from \"../../styles/utils\"\nimport \"../shared/loading-button\"\nimport { TextDiffMixin } from \"../../mixins/text-diff-mixin\"\nimport { LitElement } from \"lit\"\nimport { getValidHeadingLevel } from \"../../utils/knowledge-panels/heading-utils\"\nimport { sanitizeHtml } from \"../../utils/html\"\n\n/**\n * TextCorrectorHighlight component\n *\n * It allows the user to correct a text with the help of a list of changes.\n * It displays the text with the changes highlighted.\n * You can validate or reject the changes.\n * It also allows the user to edit the text manually.\n * The user can validates, rejects the changes, or skips the correction.\n * Validation can be done when all the changes are validated/rejected or if the user has edited the text manually.\n * @element text-corrector-highlight\n * @fires input - when the user types in the textarea\n */\n@customElement(\"text-corrector-highlight\")\nexport class TextCorrectorHighlight extends TextDiffMixin(LitElement) {\n  static override styles = [\n    BASE,\n    TEXTAREA,\n    POPOVER,\n    RELATIVE,\n    TEXT_CORRECTOR,\n    getButtonClasses([\n      ButtonType.Cappucino,\n      ButtonType.Success,\n      ButtonType.Danger,\n      ButtonType.White,\n      ButtonType.LightRed,\n      ButtonType.LightGreen,\n    ]),\n    css`\n      .submit-buttons-wrapper {\n        margin-top: 1rem;\n      }\n    `,\n  ]\n\n  /**\n   * The original text to be corrected.\n   * @type {string}\n   */\n  @property({ type: String, reflect: true })\n  original = \"\"\n\n  /**\n   * The value of the text input.\n   * @type {string}\n   */\n  @property({ type: String, reflect: true })\n  value?: string = \"\"\n\n  /**\n   * The value of the text input.\n   * @type {string}\n   */\n  @property({ type: String, reflect: true, attribute: \"heading-level\" })\n  headingLevel = \"h2\"\n\n  /**\n   * Focuses on the first updated element when the component is first updated.\n   * @type {boolean}\n   */\n  @property({ type: Boolean, reflect: true, attribute: \"focus-on-first-updated\" })\n  focusOnFirstUpdated = false\n\n  protected override firstUpdated(_changedProperties: PropertyValues): void {\n    super.firstUpdated(_changedProperties)\n    if (this.focusOnFirstUpdated) {\n      this.shadowRoot!.querySelector(\"textarea\")!.focus()\n    }\n  }\n\n  override attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n    super.attributeChangedCallback(name, _old, value)\n    if (name === \"original\" || name === \"value\") {\n      requestAnimationFrame(() => {\n        this.computeDiffResult(this.original, this.value ?? \"\")\n      })\n    }\n  }\n\n  /**\n   * Renders the highlighted diff between the original and corrected text.\n   * @returns {TemplateResult} The rendered highlighted diff.\n   */\n  renderHighlightedDiff() {\n    return html`${this.diffResult.map((part) => {\n      if (part.added) {\n        return html`<span class=\"addition\">${part.value}</span>`\n      } else if (part.removed) {\n        return html`<span class=\"deletion line-through\">${part.value}</span>`\n      } else {\n        return html`<span>${part.value}</span>`\n      }\n    })}`\n  }\n\n  /**\n   * Handles the change event of the textarea.\n   * @param {Event} e - The change event.\n   */\n  handleTextareaInput(e: Event) {\n    e.preventDefault()\n    const textarea = e.target as HTMLTextAreaElement\n    this.value = textarea.value\n  }\n\n  /**\n   * Renders the textarea for editing the text.\n   * @returns {TemplateResult} The rendered textarea.\n   */\n  override render() {\n    const headingTag = getValidHeadingLevel(this.headingLevel)\n    return html`\n      <div class=\"text-section\">\n        ${sanitizeHtml(`<${headingTag}>${msg(\"Preview\")}</${headingTag}>`)}\n        <p class=\"text-content\">${this.renderHighlightedDiff()}</p>\n      </div>\n      <div class=\"\">\n        ${sanitizeHtml(`<${headingTag}>${msg(\"Edit ingredients list\")}</${headingTag}>`)}\n        <textarea class=\"textarea\" rows=\"6\" @input=${this.handleTextareaInput}>\n${this.value}</textarea\n        >\n      </div>\n    `\n  }\n}\n\n// Define the custom element\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"text-corrector-highlight\": TextCorrectorHighlight\n  }\n}\n","import { LitElement, html, css, nothing } from \"lit\"\nimport { customElement, property, query, state } from \"lit/decorators.js\"\nimport { BASE } from \"../../styles/base\"\nimport { msg } from \"@lit/localize\"\nimport { EventType } from \"../../constants\"\nimport { AnnotationAnswer } from \"../../types/robotoff\"\nimport \"../icons/check\"\nimport \"../icons/cross\"\nimport \"../icons/skip\"\nimport \"../icons/edit\"\nimport \"../shared/info-button\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\nimport { TEXTAREA } from \"../../styles/form\"\nimport { POPOVER } from \"../../styles/popover\"\nimport { SAFE_LIGHT_BLACK, SAFE_GREY, SAFE_LIGHT_GREY } from \"../../utils/colors\"\nimport { TEXT_CORRECTOR } from \"../../styles/text-corrector\"\nimport { clickOutside } from \"../../directives/click-outside\"\nimport {\n  ChangeType,\n  type IndexedGroupedChange,\n  type TextCorrectorEventDetail,\n} from \"../../types/ingredient-spellcheck\"\nimport { RELATIVE } from \"../../styles/utils\"\nimport { sanitizeHtml } from \"../../utils/html\"\nimport { Breakpoints } from \"../../utils/breakpoints\"\n\nimport \"../shared/loading-button\"\nimport \"../shared/text-corrector-highlight\"\nimport { triggerSubmit } from \"../../utils\"\nimport { TextDiffMixin } from \"../../mixins/text-diff-mixin\"\n\n// key is the index of the change in the groupedChanges array\n// value is boolean indicating if the change is validated or not\nexport type ValidationChangeResult = Record<number, boolean>\n\nexport enum TextCorrectorKeyboardShortcut {\n  ACCEPT_FIRST_SUGGESTION = \"f\",\n  REJECT_FIRST_SUGGESTION = \"o\",\n  SKIP_TEXT_CORRECTION = \"k\",\n  EDIT_TEXT = \"e\",\n  VALIDATE_CORRECTION = \"s\",\n}\n\n/**\n * TextCorrector component\n *\n * It allows the user to correct a text with the help of a list of changes.\n * It displays the text with the changes highlighted.\n * You can validate or reject the changes.\n * It also allows the user to edit the text manually.\n * The user can validates, rejects the changes, or skips the correction.\n * Validation can be done when all the changes are validated/rejected or if the user has edited the text manually.\n * @element text-corrector\n * @fires submit - when the user submits the form\n * @fires skip - when the user skips the question\n */\n@customElement(\"text-corrector\")\nexport class TextCorrector extends TextDiffMixin(LitElement) {\n  static override styles = [\n    BASE,\n    TEXTAREA,\n    POPOVER,\n    RELATIVE,\n    TEXT_CORRECTOR,\n    getButtonClasses([ButtonType.Cappucino, ButtonType.LightRed, ButtonType.LightGreen]),\n    css`\n      .text {\n        line-height: 1.4rem;\n      }\n      .summary {\n        margin-bottom: 0.5rem;\n        padding-top: 1.5rem;\n        padding-bottom: 0rem;\n        border-bottom: 1px solid ${SAFE_LIGHT_GREY};\n        box-shadow: 0 0.5rem 2px -2px rgba(0, 0, 0, 0.1);\n      }\n\n      .submit-buttons-wrapper {\n        margin-top: 1rem;\n      }\n      .submit-buttons {\n        display: grid;\n        grid-template-columns: 1fr 1fr;\n        gap: 1rem;\n      }\n\n      .submit-buttons button {\n        justify-content: center;\n      }\n      .spellcheck {\n        padding: 2px 5px;\n        border-radius: 15px;\n        cursor: pointer;\n      }\n\n      .deletion.current {\n        outline: 2px solid red;\n      }\n      .answered-change {\n        background-color: ${SAFE_GREY};\n      }\n      .summary-item-wrapper {\n        display: flex;\n        height: 100%;\n        max-height: 180px;\n        overflow: hidden;\n        flex-direction: column;\n        gap: 1rem;\n        padding-bottom: 1rem;\n\n        margin-top: 1rem;\n\n        @media (min-width: ${Breakpoints.SM}px) {\n          max-height: none;\n          overflow: auto;\n          margin-top: 0;\n        }\n      }\n      .summary-item {\n        display: grid;\n        width: 100%;\n        grid-template-columns: 1fr 1fr;\n        gap: 0.5rem;\n        padding-left: 0.5rem;\n        padding-right: 0.5rem;\n        box-sizing: border-box;\n      }\n      .summary-item :first-child {\n        justify-self: end;\n      }\n      .summary-item :last-child {\n        justify-self: start;\n      }\n\n      .info-popover {\n        z-index: 2;\n        min-width: 200px;\n      }\n\n      .suggestion-button {\n        height: 32px;\n        font-weight: 500;\n        border-radius: 30px;\n        white-space: nowrap;\n        overflow: hidden;\n        text-overflow: ellipsis;\n        max-width: 100%;\n      }\n      .suggestion-button-title {\n        font-weight: bold;\n        text-align: center;\n      }\n      .suggestion-button,\n      .suggestion-button-title {\n        width: 100%;\n      }\n\n      .empty-suggestion {\n        color: ${SAFE_LIGHT_BLACK};\n        font-weight: bold;\n      }\n\n      .info-button-wrapper {\n        position: absolute;\n        top: -12px;\n        right: 0;\n      }\n    `,\n  ]\n  /**\n   * The original text to be corrected.\n   * @type {string}\n   */\n  @property({ type: String })\n  original = \"\"\n\n  /**\n   * The corrected text.\n   * @type {string}\n   */\n  @property({ type: String })\n  correction = \"\"\n\n  /**\n   * Enables keyboard mode for the component.\n   * @type {boolean}\n   */\n  @property({ type: Boolean, attribute: \"enable-keyboard-mode\" })\n  enableKeyboardMode = false\n\n  @state()\n  validateChangeResult: ValidationChangeResult = {}\n\n  @state()\n  currentAnsweredIndex: number = 0\n\n  /**\n   * The grouped changes based on the diff result.\n   * @type {IndexedGroupedChange[]}\n   */\n  @state()\n  groupedChanges: IndexedGroupedChange[] = []\n\n  /**\n   * The current value of the text being edited.\n   * @type {string}\n   */\n  @state()\n  value = \"\"\n\n  /**\n   * The text to compare against the current value.\n   * @type {string}\n   */\n  @state()\n  textToCompare = \"\"\n\n  /**\n   * Loading state for buttons\n   */\n  @property({ type: Number, reflect: true })\n  loading?: AnnotationAnswer\n\n  /**\n   * Indicates whether the component is in edit mode.\n   * @type {boolean}\n   */\n  @state()\n  isEditMode = false\n\n  @state()\n  showInfoPopover: boolean = false\n\n  @state()\n  resetAutoFocus: boolean = false\n\n  @query(\"form\")\n  form!: HTMLFormElement\n\n  /**\n   * Checks if the confirm button should be disabled.\n   * @returns {boolean} True if the confirm button should be disabled, false otherwise.\n   */\n  get isConfirmDisabled() {\n    return (\n      !this.isEditMode &&\n      this.groupedChanges.some((_, index) => this.validateChangeResult[index] === undefined)\n    )\n  }\n\n  /**\n   * Gets the message to display when the confirm button is disabled.\n   * @returns {string} The message to display.\n   */\n  get updateTextMsg() {\n    return msg(\"Please fix the errors or modify the text before confirming\")\n  }\n\n  get filteredNotAnsweredChanges() {\n    return this.groupedChanges.filter((_, index) => {\n      return this.validateChangeResult[index] === undefined\n    })\n  }\n\n  /**\n   * Called when an attribute is changed.\n   * @param {string} name - The name of the attribute.\n   * @param {string | null} _old - The old value of the attribute.\n   * @param {string | null} value - The new value of the attribute.\n   */\n  override attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n    super.attributeChangedCallback(name, _old, value)\n    if (name === \"original\" || name === \"correction\") {\n      this.updateValues()\n      this.computeWordDiff(true)\n      this.resetAutoFocus = true\n    }\n  }\n  /**\n   * Called when the component is first updated.\n   * Adds an event listener for the keydown event if keyboard mode is enabled.\n   */\n  override firstUpdated() {\n    if (this.enableKeyboardMode) {\n      this.form!.addEventListener(\"keydown\", this.handleKeyboardShortcut.bind(this))\n    }\n  }\n\n  /**\n   * Called when the component is disconnected from the DOM.\n   * Removes the event listener for the keydown event if keyboard mode is enabled.\n   */\n  override disconnectedCallback() {\n    super.disconnectedCallback()\n    if (this.enableKeyboardMode) {\n      this.form!.removeEventListener(\"keydown\", this.handleKeyboardShortcut.bind(this))\n    }\n  }\n\n  /**\n   * Renders the component.\n   * @returns {TemplateResult} The rendered component.\n   */\n  override render() {\n    return html`\n      <form @submit=${this.confirmText}>\n        <div>\n          ${this.isEditMode\n            ? html`<text-corrector-highlight\n                .value=${this.value}\n                original=${this.original}\n                focus-on-first-updated\n              ></text-corrector-highlight>`\n            : this.renderSpellCheck()}\n        </div>\n        <div class=\"submit-buttons-wrapper\">${this.renderButtons()}</div>\n      </form>\n    `\n  }\n\n  /**\n   * Gets the data-id attribute for the accept suggestion button.\n   * @param {number} index - The index of the suggestion.\n   * @returns {string} The data-id attribute value.\n   */\n  getAcceptSuggestionButtonDataId(index: number) {\n    return `accept-suggestion-${index}`\n  }\n\n  /**\n   * Gets the keyboard shortcut text for a given shortcut.\n   * @param {TextCorrectorKeyboardShortcut} shortcut - The keyboard shortcut.\n   * @returns {string} The keyboard shortcut text.\n   */\n  getKeyboardShortcutText(shortcut: TextCorrectorKeyboardShortcut): string {\n    if (!this.enableKeyboardMode || this.isEditMode) {\n      return \"\"\n    }\n    return ` (${shortcut.toUpperCase()})`\n  }\n  /**\n   * Updates the values of the component.\n   */\n  updateValues() {\n    this.value = this.original\n    this.textToCompare = this.correction\n  }\n\n  /**\n   * Focuses the first button in the component.\n   */\n  focusFirstButton() {\n    if (!this.enableKeyboardMode) {\n      return\n    }\n    requestAnimationFrame(() => {\n      const button = this.shadowRoot!.querySelector(\n        `[data-id^=\"${this.getAcceptSuggestionButtonDataId(0)}\"]`\n      ) as HTMLButtonElement\n      button.focus()\n    })\n  }\n\n  /**\n   * Focuses the save button in the component.\n   */\n  focusSaveButton() {\n    if (!this.enableKeyboardMode) {\n      return\n    }\n    requestAnimationFrame(() => {\n      const loadingButton = this.shadowRoot!.querySelector(\n        \"loading-button[type='submit']\"\n      ) as HTMLElement\n      if (loadingButton && loadingButton.shadowRoot) {\n        const button = loadingButton.shadowRoot.querySelector(\"button\") as HTMLButtonElement\n        button?.focus()\n      }\n    })\n  }\n\n  /**\n   * Lifecycle method called when the component is updated. It allow to focus the first button in the component when the component is updated.\n   * @param changedProperties - The properties that have changed.\n   *\n   */\n  override updated(changedProperties: Map<string, unknown>) {\n    super.updated(changedProperties)\n    if (this.resetAutoFocus) {\n      this.resetAutoFocus = false\n      this.focusFirstButton()\n    }\n  }\n\n  /**\n   * Computes the grouped changes based on the diff result.\n   * This method allows to group additions and removals in \"changed\" type.\n   * For example, if the text is \"hello world\" and the correction is \"hello universe\"\n   * The grouped change will be of type \"changed\" with the oldValue \"world\" and the newValue \"universe\"\n   * instead of remove \"world\" and add \"universe\" separately\n   */\n  computeGroupedChanges(): void {\n    this.groupedChanges = []\n    this.currentAnsweredIndex = 0\n\n    const changes = this.diffResult\n    if (changes.length === 0) {\n      return\n    }\n\n    for (let i = 0; i < changes.length; i++) {\n      const current = changes[i]\n\n      if (!current.added && !current.removed) {\n        continue\n      }\n      const nextIndex = i + 1\n      const next = nextIndex < changes.length ? changes[nextIndex] : null\n      const position = this.groupedChanges.length\n\n      if (current.removed && next && next.added) {\n        // This is a \"changed\" item (something was removed and something else was added)\n        this.groupedChanges.push({\n          type: ChangeType.CHANGED,\n          oldValue: current.value,\n          newValue: next.value,\n          indexes: [i, nextIndex],\n          position,\n        })\n\n        i++ // Skip the next item as we've already processed it\n      } else if (current.removed) {\n        // This is a pure removal\n        this.groupedChanges.push({\n          type: ChangeType.REMOVED,\n          value: current.value,\n          indexes: [i],\n          position,\n        })\n      } else if (current.added) {\n        // This is a pure addition\n        this.groupedChanges.push({\n          type: ChangeType.ADDED,\n          value: current.value,\n          indexes: [i],\n          position,\n        })\n      }\n    }\n  }\n\n  /**\n   * Computes the word-level diff between the original and corrected text.\n   * @returns {IndexedChange[]} The diff result.\n   */\n  computeWordDiff(reset: boolean = false) {\n    // Compute the diff result\n    this.computeDiffResult(this.value, this.textToCompare)\n    if (reset) {\n      this.validateChangeResult = {}\n    }\n    // Group changes to identify \"changed\" items (adjacent removed and added)\n    this.computeGroupedChanges()\n\n    return this.diffResult\n  }\n\n  goToSuggestion(index: number) {\n    this.currentAnsweredIndex = index\n    // unanswered the question if it was answered\n    this.unansweredChange(index)\n  }\n\n  unansweredChange(index: number) {\n    delete this.validateChangeResult[index]\n    this.requestUpdate()\n  }\n\n  renderChange(value: string, index: number, className: string) {\n    // Replace newlines with <br/> for HTML rendering\n    let cleanedValue = value.replace(/\\n/g, \"↩︎<br/>\")\n    // for other clean value like the suggestions\n    cleanedValue = this.cleanSuggestion(cleanedValue)\n\n    const isCurrent = this.currentAnsweredIndex === index\n\n    return html`<span\n      class=\"${className} spellcheck ${isCurrent ? \"current\" : \"\"}\"\n      @click=${() => this.goToSuggestion(index)}\n      >${sanitizeHtml(cleanedValue)}</span\n    >`\n  }\n\n  renderUnansweredChange(value: string, index: number) {\n    return this.renderChange(value, index, \"deletion\")\n  }\n\n  renderAnsweredChange(value: string, index: number) {\n    return this.renderChange(value, index, \"answered-change\")\n  }\n\n  renderSpellCheckDiff() {\n    let indexedGroupedChangeIndex = 0\n\n    return html`${this.diffResult.map((part) => {\n      const indexedGroupedChange = this.groupedChanges[indexedGroupedChangeIndex]\n\n      // If the part is the second index of a grouped change, we will increment the change index\n      if (indexedGroupedChange?.indexes[1] === part.index) {\n        indexedGroupedChangeIndex++\n        return nothing\n        // If the part is part of a grouped change\n      } else if (indexedGroupedChange?.indexes[0] === part.index) {\n        const currentIndex = indexedGroupedChangeIndex\n        const isValidate = this.validateChangeResult[indexedGroupedChangeIndex]\n        // We will increment change index with the second index of the grouped change\n        if (indexedGroupedChange.type !== ChangeType.CHANGED) {\n          indexedGroupedChangeIndex++\n        }\n\n        switch (indexedGroupedChange.type) {\n          case ChangeType.ADDED:\n            if (isValidate === undefined) {\n              return this.renderUnansweredChange(\"\", currentIndex)\n            }\n            return this.renderAnsweredChange(\n              isValidate ? indexedGroupedChange.value! : \"\",\n              currentIndex\n            )\n          case ChangeType.REMOVED:\n            if (isValidate === undefined) {\n              return this.renderUnansweredChange(indexedGroupedChange.value!, currentIndex)\n            }\n            return this.renderAnsweredChange(\n              isValidate ? \"\" : indexedGroupedChange.value!,\n              currentIndex\n            )\n          case ChangeType.CHANGED:\n            if (isValidate === undefined) {\n              return this.renderUnansweredChange(indexedGroupedChange.oldValue!, currentIndex)\n            }\n            return this.renderAnsweredChange(\n              isValidate ? indexedGroupedChange.newValue! : indexedGroupedChange.oldValue!,\n              currentIndex\n            )\n        }\n      }\n      // If the part is not part of a grouped change\n      return html`<span>${part.value}</span>`\n    })}`\n  }\n\n  // Renders the empty suggestion when value is empty\n  renderEmptySuggestion() {\n    return \"\"\n  }\n\n  /**\n   * Cleans the suggestion by replacing spaces and newlines with special characters.\n   * @param {string} suggestion - The suggestion to clean.\n   * @returns {string} The cleaned suggestion.\n   */\n  cleanSuggestion(suggestion: string): string {\n    if (!suggestion) {\n      return this.renderEmptySuggestion()\n    }\n    let value = suggestion\n    // Check if value contains only spaces or newlines\n    if (value.match(/^( |\\u00A0|\\n)+$/)) {\n      value = value.replace(/( |\\u00A0)/g, \"␣\")\n    }\n    // Replace newlines with ↩︎\n    return value.replace(/\\n/g, \"↩︎\")\n  }\n\n  /**\n   * Renders the button for accepting a suggestion.\n   * @param {IndexedGroupedChange} item - The suggestion to render the button for.\n   * @param {number} index - The row index of the suggestion. This parameter is different of index of changes.\n   * @returns {TemplateResult} The rendered button.\n   */\n  renderAcceptSuggestionButton(item: IndexedGroupedChange, index: number) {\n    let text\n    let keyboardShortcutText\n    switch (item.type) {\n      case ChangeType.CHANGED:\n        text = `${this.cleanSuggestion(item.newValue!)}`\n        break\n      case ChangeType.ADDED:\n        text = `${this.cleanSuggestion(item.value!)}`\n        break\n      case ChangeType.REMOVED:\n        text = this.renderEmptySuggestion()\n        break\n    }\n    return html`\n      <button\n        class=\"suggestion-button button light-green-button small\"\n        @click=\"${() => this.updateResult(true, [item])}\"\n        tabindex=\"1\"\n        data-id=\"${this.getAcceptSuggestionButtonDataId(index)}\"\n        title=\"${text}\"\n      >\n        ${text}${keyboardShortcutText}\n      </button>\n    `\n  }\n\n  /**\n   * Renders the button for rejecting a suggestion.\n   * @param {IndexedGroupedChange} item - The suggestion to render the button for.\n   * @param {number} index - The row index of the suggestion. This parameter is different of index of changes.\n   * @returns {TemplateResult} The rendered button.\n   */\n  renderRejectSuggestionButton(item: IndexedGroupedChange) {\n    let text\n    let keyboardShortcutText\n    switch (item.type) {\n      case ChangeType.CHANGED:\n        // replace espace and espace insecable with a visible character\n        text = `${this.cleanSuggestion(item.oldValue!)}`\n        break\n      case ChangeType.ADDED:\n        text = this.renderEmptySuggestion()\n        break\n      case ChangeType.REMOVED:\n        text = this.cleanSuggestion(item.value!)\n        break\n    }\n    return html`<button\n      class=\"suggestion-button button light-red-button small\"\n      @click=\"${() => this.updateResult(false, [item])}\"\n      tabindex=\"2\"\n      title=\"${text}\"\n    >\n      ${text}${keyboardShortcutText}\n    </button>`\n  }\n\n  /**\n   * Renders a summary item content.\n   * @param {Object} params - The parameters for rendering the summary item.\n   * @param {IndexedGroupedChange} params.item - The suggestion to render.\n   * @param {string} params.oldValue - The old value.\n   * @param {string} params.newValue - The new value.\n   * @param {string} [params.oldValueClass] - The class for the old value.\n   * @param {string} [params.newValueClass] - The class for the new value.\n   * @returns {TemplateResult} The rendered summary item.\n   * */\n  renderSummaryItemContent(item: IndexedGroupedChange, index: number) {\n    return html`\n      <div class=\"summary-item\">\n        ${this.renderRejectSuggestionButton(item)} ${this.renderAcceptSuggestionButton(item, index)}\n      </div>\n    `\n  }\n\n  /**\n   * Toggles the info popover.\n   */\n  toggleInfoPopover() {\n    this.showInfoPopover = !this.showInfoPopover\n  }\n\n  /**\n   * Closes the info popover.\n   */\n  closeInfoPopover() {\n    this.showInfoPopover = false\n  }\n\n  /**\n   * Renders the content of the summary.\n   * @returns {TemplateResult} The rendered summary content.\n   */\n  renderSummary() {\n    let filteredNotAnsweredChanges = this.filteredNotAnsweredChanges\n    if (filteredNotAnsweredChanges.length === 0) {\n      return nothing\n    }\n\n    let notAnsweredChanges = [\n      // Get next items from currentAnsweredIndex first\n      ...filteredNotAnsweredChanges.filter(\n        (change) => change.position >= this.currentAnsweredIndex\n      ),\n      // Then add items before currentAnsweredIndex\n      ...filteredNotAnsweredChanges.filter((change) => change.position < this.currentAnsweredIndex),\n    ]\n\n    return html`<div class=\"summary\">\n      <div class=\"relative\">\n        <div class=\"info-button-wrapper\">\n          <info-button @click=${this.toggleInfoPopover}></info-button>\n          ${this.renderInfoPopover()}\n        </div>\n      </div>\n      <div class=\"summary-item-wrapper\">\n        <div class=\"summary-item\">\n          <div class=\"suggestion-button-title\">\n            ${msg(\"Original\")}${this.getKeyboardShortcutText(\n              TextCorrectorKeyboardShortcut.REJECT_FIRST_SUGGESTION\n            )}\n          </div>\n          <div class=\"suggestion-button-title\">\n            ${msg(\"Suggested fix\")}${this.getKeyboardShortcutText(\n              TextCorrectorKeyboardShortcut.ACCEPT_FIRST_SUGGESTION\n            )}\n          </div>\n        </div>\n\n        ${notAnsweredChanges.map((item, index) => {\n          return this.renderSummaryItemContent(item, index)\n        })}\n      </div>\n    </div>`\n  }\n\n  /**\n   * Updates the index of the next answered change.\n   * If the current change is not answered, it finds the next unanswered change.\n   * If there are no unanswered changes, it resets the index to 0.\n   * @returns {void}\n   */\n  updateNextAnsweredIndex() {\n    // If the current change is not answered, we don't update the index\n    if (this.validateChangeResult[this.currentAnsweredIndex] === undefined) {\n      return\n    }\n\n    const filteredNotAnsweredChanges = this.filteredNotAnsweredChanges\n    // If there are no unanswered changes, we reset the index to 0\n    if (filteredNotAnsweredChanges.length === 0) {\n      this.currentAnsweredIndex = 0\n      // focus on the save button to allow the user to save the result when all changes are answered\n      this.focusSaveButton()\n      return\n    }\n    // get the next unanswered change after the current one\n    const nextFilteredNotAnsweredChanges = filteredNotAnsweredChanges.filter(\n      (change) => change.position > this.currentAnsweredIndex\n    )\n\n    // If there are no unanswered changes after the current one, we take the first one\n    this.currentAnsweredIndex =\n      nextFilteredNotAnsweredChanges.length > 0\n        ? nextFilteredNotAnsweredChanges[0].position\n        : filteredNotAnsweredChanges[0].position\n\n    // focus on the next unanswered change\n    this.focusFirstButton()\n  }\n\n  /**\n   * Updates the result based on the validation of a suggestion.\n   * @param {boolean} validate - Whether to validate the suggestion.\n   * @param {IndexedGroupedChange} items - The suggestions to update the result for.\n   */\n  updateResult(validate: boolean, items: IndexedGroupedChange[]) {\n    // Do this if keyboard shortcut is used but all changes are answered\n    if (this.filteredNotAnsweredChanges.length === 0) {\n      return\n    }\n\n    items.forEach((item) => {\n      this.validateChangeResult[item.position] = validate\n    })\n    this.updateNextAnsweredIndex()\n    this.requestUpdate()\n  }\n\n  /**\n   * Dispatches a submit event with the provided detail.\n   * @param {object} detail - The detail of the event.\n   * @param {string} [detail.correction] - The correction to include in the event.\n   * @param {AnnotationAnswer} detail.type - The type of the event.\n   */\n  dispatchSubmitEvent(detail: TextCorrectorEventDetail) {\n    this.dispatchEvent(new CustomEvent<TextCorrectorEventDetail>(EventType.SAVE, { detail }))\n  }\n\n  /**\n   * Gets the value of a grouped change based on the validation result.\n   * If groupedChange is not answered, it returns the original value.\n   * If groupedChange is answered, it returns the value based on the validation result.\n   * @param {IndexedGroupedChange} groupedChange - The grouped change.\n   * @returns {string} The value of the grouped change.\n   */\n  getValueOfGroupedChange(groupedChange: IndexedGroupedChange): string {\n    // get value of grouped change based on the validateChangeResult\n    const result = this.validateChangeResult[groupedChange.position]\n    switch (groupedChange.type) {\n      case ChangeType.ADDED:\n        return result ? groupedChange.value! : \"\"\n      case ChangeType.REMOVED:\n        return result ? \"\" : groupedChange.value!\n      case ChangeType.CHANGED:\n        return result ? groupedChange.newValue! : groupedChange.oldValue!\n      default:\n        return \"\"\n    }\n  }\n\n  buildValueWithAnsweredChanges() {\n    let value = \"\"\n    let groupedChangesIndex = 0\n    for (let index = 0; index < this.diffResult.length; index++) {\n      const item = this.diffResult[index]\n      const indexedGroupedChange = this.groupedChanges[groupedChangesIndex]\n      if (indexedGroupedChange?.indexes.includes(index)) {\n        value += this.getValueOfGroupedChange(indexedGroupedChange)\n        // Go to next grouped change\n        groupedChangesIndex++\n        if (indexedGroupedChange.type === ChangeType.CHANGED) {\n          // Skip next part of the diff result because changed type is composed of two parts\n          index++\n        }\n      } else {\n        value += item.value\n      }\n    }\n    return value\n  }\n\n  /**\n   * Accepts the text with a correction.\n   */\n  acceptTextWithCorrection() {\n    this.dispatchSubmitEvent({\n      correction: this.value,\n      annotation: AnnotationAnswer.ACCEPT_AND_ADD_DATA,\n    })\n  }\n  /**\n   * Accepts the text.\n   */\n  acceptText() {\n    this.dispatchSubmitEvent({ annotation: AnnotationAnswer.ACCEPT })\n  }\n  /**\n   * Confirms the text.\n   */\n  confirmText(event?: SubmitEvent) {\n    event?.preventDefault()\n    // If there are answered changes, we don't want to submit the form\n    if (!this.isEditMode && this.filteredNotAnsweredChanges.length) {\n      return\n    }\n    // Build the value with the answered changes if we are not in edit mode\n    if (!this.isEditMode) {\n      this.value = this.buildValueWithAnsweredChanges()\n    }\n    this.isEditMode = false\n\n    if (this.correction === this.value) {\n      this.acceptText()\n    } else if (this.original === this.value) {\n      this.rejectText()\n    } else {\n      this.acceptTextWithCorrection()\n    }\n  }\n  /**\n   * Rejects the text.\n   */\n  rejectText() {\n    this.dispatchSubmitEvent({ annotation: AnnotationAnswer.REFUSE })\n  }\n  /**\n   * Skips the text.\n   */\n  skip() {\n    this.dispatchSubmitEvent({ annotation: AnnotationAnswer.SKIP })\n  }\n\n  /**\n   * Enters edit mode.\n   */\n  enterEditMode() {\n    this.isEditMode = true\n    this.value = this.buildValueWithAnsweredChanges()\n  }\n\n  /**\n   * Cancels edit mode.\n   */\n  cancelEditMode() {\n    this.updateValues()\n    this.isEditMode = false\n    this.computeWordDiff()\n    this.filteredNotAnsweredChanges.length ? this.focusFirstButton() : this.focusSaveButton()\n  }\n\n  /**\n   * Renders the buttons of the component.\n   * @returns {TemplateResult} The rendered buttons.\n   */\n  renderButtons() {\n    const confirmTitle = this.isConfirmDisabled ? this.updateTextMsg : \"\"\n\n    const isLoading = Boolean(this.loading)\n    const isSuccessLoading = [\n      AnnotationAnswer.ACCEPT,\n      AnnotationAnswer.ACCEPT_AND_ADD_DATA,\n      AnnotationAnswer.REFUSE,\n    ].includes(this.loading!)\n    const successButton = html` <loading-button\n      ?loading=${isSuccessLoading}\n      ?disabled=${isLoading || this.isConfirmDisabled}\n      type=\"submit\"\n      title=${confirmTitle}\n      @click=${() => triggerSubmit(this.form!)}\n      css-classes=\"button success-button\"\n    >\n      <span\n        >${msg(\"Save\")}${this.getKeyboardShortcutText(\n          TextCorrectorKeyboardShortcut.VALIDATE_CORRECTION\n        )}</span\n      >\n      <check-icon></check-icon>\n    </loading-button>`\n\n    if (this.isEditMode) {\n      return html`\n        <div class=\"submit-buttons buttons-row can-wrap\">\n          <button\n            class=\"button cappucino-button with-icon\"\n            @click=${this.cancelEditMode}\n            ?disabled=${isLoading}\n          >\n            <span>${msg(\"Cancel\")}</span><cross-icon></cross-icon>\n          </button>\n          ${successButton}\n        </div>\n      `\n    }\n\n    return html`\n      <div class=\"submit-buttons buttons-row can-wrap\">\n        <loading-button\n          ?loading=${this.loading === AnnotationAnswer.SKIP}\n          ?disabled=${isLoading}\n          css-classes=\"button white-button\"\n          @click=${this.skip}\n        >\n          <span\n            >${msg(\"Skip\")}${this.getKeyboardShortcutText(\n              TextCorrectorKeyboardShortcut.SKIP_TEXT_CORRECTION\n            )}</span\n          ><skip-icon></skip-icon>\n        </loading-button>\n        ${successButton}\n      </div>\n    `\n  }\n\n  renderSpellCheck() {\n    const isLoading = Boolean(this.loading)\n    return html`\n      <div class=\"text-section\">\n        <p class=\"text\">${this.renderSpellCheckDiff()}</p>\n        <div style=\"display: flex; justify-content: flex-end;\">\n          <button\n            class=\"button cappucino-button with-icon\"\n            @click=${this.enterEditMode}\n            ?disabled=${isLoading}\n          >\n            <span\n              >${msg(\"Edit\")}${this.getKeyboardShortcutText(\n                TextCorrectorKeyboardShortcut.EDIT_TEXT\n              )}</span\n            ><edit-icon></edit-icon>\n          </button>\n        </div>\n      </div>\n      ${this.renderSummary()}\n    `\n  }\n\n  /**\n   * Handles the keyboard shortcuts.\n   * @param {KeyboardEvent} event - The keyboard event.\n   */\n  private handleKeyboardShortcut(event: KeyboardEvent) {\n    if (!this.enableKeyboardMode || this.isEditMode) {\n      return\n    }\n    switch (event.key) {\n      case TextCorrectorKeyboardShortcut.ACCEPT_FIRST_SUGGESTION:\n        this.updateResult(true, [this.groupedChanges[this.currentAnsweredIndex]])\n        break\n      case TextCorrectorKeyboardShortcut.REJECT_FIRST_SUGGESTION:\n        this.updateResult(false, [this.groupedChanges[this.currentAnsweredIndex]])\n        break\n      case TextCorrectorKeyboardShortcut.SKIP_TEXT_CORRECTION:\n        this.skip()\n        break\n      case TextCorrectorKeyboardShortcut.EDIT_TEXT:\n        this.enterEditMode()\n        event.preventDefault()\n        break\n      case TextCorrectorKeyboardShortcut.VALIDATE_CORRECTION:\n        this.confirmText()\n        break\n    }\n  }\n\n  /**\n   * Renders the info popover.\n   * @returns {TemplateResult} The rendered info popover.\n   */\n  renderInfoPopover() {\n    if (!this.showInfoPopover) {\n      return nothing\n    }\n    return html`\n      <div class=\"popover popover-left info-popover\" ${clickOutside(() => this.closeInfoPopover())}>\n        <div class=\"popover-content\">\n          <p>\n            ${msg(\n              html`This tool allows you to correct the ingredients list. You can add, remove or edit\n                ingredients list.\n                <br />\n                This character <span class=\"highlight\">␣</span> represents a space.\n                <br />\n                This character <span class=\"highlight\">↩︎</span> represents a line break. `\n            )}\n          </p>\n        </div>\n      </div>\n    `\n  }\n}\n\n// Define the custom element\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"text-corrector\": TextCorrector\n  }\n}\n","import { LitElement, html, css, nothing } from \"lit\"\nimport { LoadingWithTimeoutMixin } from \"../../mixins/loading-with-timeout-mixin\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { BASE } from \"../../styles/base\"\nimport { localized, msg } from \"@lit/localize\"\nimport { Task } from \"@lit/task\"\nimport {\n  fetchSpellcheckInsights,\n  ingredientSpellcheckInsights,\n} from \"../../signals/ingredient-spellcheck\"\nimport { AnnotationAnswer, type IngredientSpellcheckInsight } from \"../../types/robotoff\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\nimport robotoff from \"../../api/robotoff\"\nimport { EventState, EventType } from \"../../constants\"\nimport \"./text-corrector\"\nimport \"../shared/zoomable-image\"\nimport { fetchProduct } from \"../../api/openfoodfacts\"\nimport type { ImageIngredientsProductType } from \"../../types/openfoodfacts\"\nimport type {\n  RobotoffIngredientsStateEventDetail,\n  TextCorrectorEvent,\n} from \"../../types/ingredient-spellcheck\"\nimport { INPUT } from \"../../styles/form\"\nimport { getValidHeadingLevel } from \"../../utils/knowledge-panels/heading-utils\"\nimport { sanitizeHtml } from \"../../utils/html\"\nimport { getFullImageUrl, ProductFields } from \"../../utils/openfoodfacts\"\nimport { mobileAndTabletCheck } from \"../../utils/breakpoints\"\nimport { ifDefined } from \"lit/directives/if-defined.js\"\nimport { LanguageCodesMixin } from \"../../mixins/language-codes-mixin\"\nimport { DisplayProductLinkMixin } from \"../../mixins/display-product-link-mixin\"\n\n/**\n * RobotoffIngredients component\n * It allows the user to correct the ingredients list of a product\n * with the help of robotoff that suggests corrections.\n * It handle the data fetching and the state management.\n * It also handle the user interactions and the form submission.\n * It uses the `text-corrector` component to handle the text correction.\n * @element robotoff-ingredient-spellcheck\n * @fires state - when the state of the component changes\n * @fires submit - when the user submits the form\n * @slot complete - The content to display when the component is complete\n * @slot pending - The content to display when the component is pending\n */\n@customElement(\"robotoff-ingredient-spellcheck\")\n@localized()\nexport class RobotoffIngredientSpellcheck extends DisplayProductLinkMixin(\n  LoadingWithTimeoutMixin(LanguageCodesMixin(LitElement), undefined as AnnotationAnswer | undefined)\n) {\n  static override styles = [\n    BASE,\n    INPUT,\n    getButtonClasses([ButtonType.Cappucino, ButtonType.Success, ButtonType.Danger]),\n    css`\n      .robotoff-ingredient-spellcheck {\n        max-width: 800px;\n        margin: 0 auto;\n        border-radius: 4px;\n        box-sizing: border-box;\n      }\n\n      .robotoff-ingredient-spellcheck-title {\n        margin-top: 0;\n        margin-bottom: 1rem;\n      }\n    `,\n  ]\n  /**\n   * The HTML tag level for the title of the component.\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"title-level\" })\n  titleLevel = \"h2\"\n\n  /**\n   * The product code for which the ingredients are being corrected.\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"product-code\", reflect: true })\n  productCode?: string = undefined\n\n  /**\n   * Enables keyboard mode for the component.\n   * @type {boolean}\n   */\n  @property({ type: Boolean, attribute: \"enable-keyboard-mode\" })\n  enableKeyboardMode = false\n\n  /**\n   * The current index of the insight being displayed.\n   * @type {number}\n   */\n  @state()\n  private _currentIndex = 0\n\n  /**\n   * An array of insight IDs for the product.\n   * @type {string[]}\n   */\n  @state()\n  private _insightIds: string[] = []\n\n  /**\n   * The product data, including the image URL and name.\n   * @type {{ imageUrl?: string, name?: string }}\n   */\n  @state()\n  private productData: {\n    imageUrl?: string\n    name?: string\n  } = {}\n\n  /**\n   * Gets the full image URL by replacing the '400.jpg' suffix with 'full.jpg'.\n   * @returns {string | undefined} The full image URL or undefined if no image URL is available.\n   */\n  get fullImageUrl() {\n    return getFullImageUrl(this.productData.imageUrl)\n  }\n\n  /**\n   * Checks if all insights have been answered.\n   * @returns {boolean} True if all insights are answered, false otherwise.\n   */\n  get allInsightsAreAnswered() {\n    return this._currentIndex >= this._insightIds.length\n  }\n\n  /**\n   * Gets the current insight based on the current index.\n   * @returns {IngredientSpellcheckInsight | undefined} The current insight or undefined if no insight is available.\n   */\n  get _insight(): IngredientSpellcheckInsight | undefined {\n    const id: string | undefined = this._insightIds[this._currentIndex]\n    const value = ingredientSpellcheckInsights.getItem(id)\n    return value\n  }\n\n  /**\n   * Gets the value of enableKeyboardMode, considering mobile and tablet devices.\n   */\n  get _enable_keyboard_mode() {\n    // Disable keyboard mode on mobile and tablet devices\n    return this.enableKeyboardMode ? !mobileAndTabletCheck() : false\n  }\n\n  /**\n   * Renders the header of the component.\n   * @returns {TemplateResult} The rendered header.\n   */\n  renderHeader() {\n    const headingLevel = getValidHeadingLevel(this.titleLevel)\n    const title = `<${headingLevel} class=\"robotoff-ingredient-spellcheck-title\">${msg(\"Help us fix errors in ingredients list\")}</${headingLevel}>`\n    return html`\n      <div>\n        <div>${sanitizeHtml(title)}</div>\n      </div>\n    `\n  }\n\n  /**\n   * Updates the value based on the current insight.\n   */\n  updateValue() {\n    const insight = this._insight\n    this.updateIngredientsImageUrl(insight)\n  }\n\n  /**\n   * Updates the ingredients image URL based on the provided insight.\n   * @param {IngredientSpellcheckInsight | undefined} insight - The insight to use for updating the image URL.\n   */\n  async updateIngredientsImageUrl(insight?: IngredientSpellcheckInsight) {\n    if (!insight) {\n      this.productData.imageUrl = undefined\n      this.productData.name = undefined\n      return\n    }\n    const result = await fetchProduct<ImageIngredientsProductType>(insight.barcode, {\n      lc: insight.data.lang,\n      fields: [ProductFields.IMAGE_INGREDIENTS_URL, ProductFields.PRODUCT_NAME],\n    })\n\n    this.productData = {\n      imageUrl: result.product.image_ingredients_url,\n      name: result.product.product_name,\n    }\n  }\n\n  /**\n   * A task to fetch spellcheck insights for the product.\n   * @type {Task}\n   */\n  private _spellcheckTask = new Task(this, {\n    task: async ([productCode]) => {\n      this._insightIds = []\n      this._currentIndex = 0\n      this.dispatchIngredientSpellcheckStateEvent({\n        state: EventState.LOADING,\n      })\n      const insights = await fetchSpellcheckInsights(productCode ? productCode : undefined, {\n        lc: this._languageCodes,\n      })\n      this._insightIds = insights\n        // Currently we filter by lang here but we should do it in the API when is available\n        .map((insight) => insight.id)\n      this.updateValue()\n      this.dispatchIngredientSpellcheckStateEvent({\n        state: this._insightIds.length ? EventState.HAS_DATA : EventState.NO_DATA,\n      })\n    },\n    args: () => [this.productCode, ...this._languageCodes],\n  })\n\n  /**\n   * Moves to the next insight and updates the value if not all insights are answered.\n   */\n  nextInsight() {\n    this._currentIndex++\n    if (!this.allInsightsAreAnswered) {\n      this.updateValue()\n    }\n  }\n\n  /**\n   * Dispatches an ingredient spellcheck state event with the provided detail.\n   * @param {RobotoffIngredientsStateEventDetail} detail - The detail of the event.\n   */\n  dispatchIngredientSpellcheckStateEvent(detail: RobotoffIngredientsStateEventDetail) {\n    this.dispatchEvent(\n      new CustomEvent<RobotoffIngredientsStateEventDetail>(EventType.INGREDIENT_SPELLCHECK_STATE, {\n        bubbles: true,\n        composed: true,\n        detail: {\n          productCode: this.productCode,\n          ...detail,\n        },\n      })\n    )\n  }\n\n  /**\n   * After the insight has been annotated\n   * Remove Loading state and emit event annotated\n   * Load the next insight\n   * @returns {Promise<void>}\n   */\n  async afterInsightAnnotation() {\n    await this.hideLoading()\n    this.dispatchIngredientSpellcheckStateEvent({\n      state: EventState.ANNOTATED,\n    })\n    this.nextInsight()\n  }\n\n  /**\n   * Submits an annotation based on the provided event.\n   * @param {TextCorrectorEvent} event - The event containing the annotation details.\n   */\n  async submitAnnotation(event: TextCorrectorEvent) {\n    this.showLoading(event.detail.annotation)\n    const insight = this._insight\n    if (!insight) {\n      console.error(\"No insight found at index\", this._currentIndex)\n      return\n    }\n\n    // Send the annotation to Robotoff API\n    await robotoff.annotateIngredientSpellcheck(\n      insight.id,\n      event.detail.annotation,\n      event.detail.correction\n    )\n\n    await this.afterInsightAnnotation()\n\n    if (this.allInsightsAreAnswered) {\n      this.dispatchIngredientSpellcheckStateEvent({\n        state: EventState.FINISHED,\n        insightId: insight.id,\n        ...event.detail,\n      })\n    }\n  }\n\n  /**\n   * Renders the image based on the full image URL.\n   * @returns {TemplateResult | typeof nothing} The rendered image or nothing if no image URL is available.\n   */\n  renderImage() {\n    if (!this.fullImageUrl) {\n      return nothing\n    }\n    return html`\n      <div>\n        <zoomable-image\n          src=${this.fullImageUrl}\n          fallback-src=${this.productData.imageUrl ?? \"\"}\n          .size=\"${{ width: \"100%\", height: \"30vh\" }}\"\n          show-buttons\n        ></zoomable-image>\n      </div>\n    `\n  }\n  /**\n   * Renders the component based on the spellcheck task state.\n   * @returns {TemplateResult} The rendered component.\n   */\n  override render() {\n    return this._spellcheckTask.render({\n      pending: () => html`<slot name=\"pending\"><off-wc-loader></off-wc-loader></slot>`,\n      complete: () => {\n        const insight = this._insight\n        if (this.allInsightsAreAnswered) {\n          return html`<slot name=\"complete\">\n            <p>${msg(\"All insights have been answered! Thanks for your help!\")}</p>\n          </slot>`\n        }\n        if (!insight) {\n          return nothing\n        }\n\n        const correction = insight.data.correction\n        const original = insight.data.original\n\n        return html`\n          <div class=\"robotoff-ingredient-spellcheck\">\n            ${this.renderHeader()}\n            <div>\n              ${this.renderProductLink(insight.barcode)} ${this.renderImage()}\n              <div>\n                <text-corrector\n                  loading=${ifDefined(this.loading) as AnnotationAnswer}\n                  correction=${correction}\n                  original=${original}\n                  @save=${this.submitAnnotation}\n                  ?enable-keyboard-mode=${this._enable_keyboard_mode}\n                ></text-corrector>\n              </div>\n            </div>\n          </div>\n        `\n      },\n    })\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"robotoff-ingredient-spellcheck\": RobotoffIngredientSpellcheck\n  }\n}\n","import { css } from \"lit\"\n\nexport const CONTAINER = css`\n  .container {\n    max-width: 1200px;\n    margin: 0 auto;\n  }\n`\n","import { css } from \"lit\"\n\nexport const MODAL = css`\n  :host {\n    display: block;\n    font-family: Arial, sans-serif;\n  }\n\n  .modal {\n    position: fixed;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    background: white;\n    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);\n    border-radius: 12px;\n    z-index: 1000;\n    max-height: 90%;\n    width: 95%;\n    max-width: 500px;\n    overflow-y: auto;\n    box-sizing: border-box;\n    animation: fadeIn 0.3s ease-in-out;\n  }\n\n  .overlay {\n    position: fixed;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    background: rgba(0, 0, 0, 0.6);\n    z-index: 999;\n    animation: fadeIn 0.3s ease-in-out;\n    cursor: pointer;\n  }\n\n  h2 {\n    margin: 0;\n    font-size: 1.5rem;\n    color: #333;\n    text-align: center;\n  }\n\n  .modal-buttons {\n    display: flex;\n    justify-content: space-between;\n  }\n\n  .modal-header {\n    position: sticky;\n    top: 0.5rem;\n    display: flex;\n    justify-content: flex-end;\n  }\n\n  .modal-body {\n    padding: 0rem 2rem 1rem 2rem;\n  }\n\n  .close-icon {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    width: 2rem;\n    height: 2rem;\n    border: 1px solid;\n    border-color: transparent;\n    border-radius: 50%;\n    cursor: pointer;\n    background: transparent;\n  }\n\n  .close-icon:hover {\n    border-color: black;\n  }\n\n  @keyframes fadeIn {\n    from {\n      opacity: 0;\n    }\n    to {\n      opacity: 1;\n    }\n  }\n`\n","import { LitElement, html, nothing } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { MODAL } from \"../../styles/modal\"\nimport \"./loader\"\nimport { EventType } from \"../../constants\"\nimport \"../icons/cross\"\nimport { localized, msg } from \"@lit/localize\"\n\n/**\n * The `modal-component` is a reusable web component that displays a modal dialog.\n * It can be used to show content in a modal overlay, with options for loading states and close functionality.\n *\n * @fires close - Dispatched when the modal is closed.\n *\n * @slot - The default slot for the modal content.\n *\n * @example\n * ```html\n * <modal-component is-open=\"true\" is-loading=\"false\">\n *   <p>This is the content of the modal.</p>\n * </modal-component>\n * ```\n */\n\n@customElement(\"modal-component\")\n@localized()\nclass ModalComponent extends LitElement {\n  static override styles = [MODAL]\n\n  /**\n   * Indicates whether the modal is open.\n   */\n  @property({\n    type: Boolean,\n    reflect: true,\n    attribute: \"is-open\",\n  })\n  isOpen = false\n\n  /**\n   * Indicates whether the modal is in a loading state.\n   */\n  @property({ type: Boolean, attribute: \"is-loading\" })\n  isLoading = false\n\n  /**\n   * Closes the modal and dispatches a close event.\n   */\n  closeModal() {\n    this.dispatchEvent(new CustomEvent(EventType.CLOSE))\n  }\n\n  override render() {\n    if (!this.isOpen) {\n      return nothing\n    }\n    return html`\n      <div class=\"overlay\" @click=\"${this.closeModal}\" aria-hidden=\"true\"></div>\n      <div class=\"modal\">\n        <div class=\"modal-content\">\n          <div class=\"modal-header\">\n            <button class=\"close-icon\" @click=\"${this.closeModal}\" aria-label=${msg(\"Close modal\")}>\n              <cross-icon></cross-icon>\n            </button>\n          </div>\n          <div class=\"modal-body\">\n            ${this.isLoading ? html`<off-wc-loader></off-wc-loader>` : html`<slot></slot>`}\n          </div>\n        </div>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"modal-component\": ModalComponent\n  }\n}\n","import robotoff from \"../api/robotoff\"\nimport {\n  type IngredientDetectionInsight,\n  type InsightsRequestParams,\n  InsightType,\n} from \"../types/robotoff\"\nimport { SignalMap } from \"../utils/signals\"\n\nexport const ingredientDetectionInsights = new SignalMap<IngredientDetectionInsight>({})\n\nexport const fetchIngredientsDetectionInsights = async (\n  productCode?: string,\n  requestParams: InsightsRequestParams = {}\n) => {\n  const params: InsightsRequestParams = {\n    ...requestParams,\n    insight_types: InsightType.ingredient_detection,\n    annotated: false,\n  }\n  if (productCode) {\n    params[\"barcode\"] = productCode\n  }\n  const response = await robotoff.insights<IngredientDetectionInsight>(params)\n\n  response.insights.forEach((insight) => {\n    ingredientDetectionInsights.setItem(insight.id, insight)\n  })\n\n  return response.insights\n}\n","import type { CropperImageBoundingBox } from \"../types\"\nimport type { RobotoffBoundingBox } from \"../types/robotoff\"\n\n/**\n * Converts a bounding box from the robotoff format to the crop image format.\n * @param boundingBox - The bounding box in the robotoff format.\n * @example [0, 0.407234539089848, 0.872586872586873, 0.998833138856476]\n * @returns The bounding box in the cropperjs image format.\n */\nexport const robotoffBoundingBoxToCropImageBoundingBox = (\n  boundingBox: RobotoffBoundingBox,\n  imageWidth: number,\n  imageHeight: number\n): CropperImageBoundingBox => {\n  const [xMin, yMin, xMax, yMax] = boundingBox // values is a value between 0 and 1\n\n  return {\n    x: yMin * imageWidth,\n    y: xMin * imageHeight,\n    width: (yMax - yMin) * imageWidth,\n    height: (xMax - xMin) * imageHeight,\n  }\n}\n\n/**\n * Converts a bounding box from the crop image format to the robotoff format.\n * @param boundingBox - The bounding box in the cropperjs image format.\n * @returns The bounding box in the robotoff format.\n */\nexport const cropImageBoundingBoxToRobotoffBoundingBox = (\n  boundingBox: CropperImageBoundingBox,\n  imageWidth: number,\n  imageHeight: number\n): RobotoffBoundingBox => {\n  const { x, y, width, height } = boundingBox\n  const xMin = y / imageHeight\n  const yMin = x / imageWidth\n  const xMax = (y + height) / imageHeight\n  const yMax = (x + width) / imageWidth\n  return [xMin, yMin, xMax, yMax]\n}\n","/**\n * RobotoffIngredientDetectionForm Component\n *\n * This component handles the form part of ingredient detection, including\n * the crop interaction and answer buttons for the Robotoff application.\n *\n * @element robotoff-ingredient-detection-form\n */\n\nimport { LitElement, css, html, nothing } from \"lit\"\nimport { customElement, property, query, state } from \"lit/decorators.js\"\nimport \"../shared/zoomable-image\"\nimport {\n  type IngredientDetectionInsight,\n  type IngredientDetectionAnnotationData,\n  AnnotationAnswer,\n} from \"../../types/robotoff\"\nimport { getRobotoffImageUrl } from \"../../signals/robotoff\"\nimport { localized, msg } from \"@lit/localize\"\nimport { FLEX } from \"../../styles/utils\"\nimport type { CropResult } from \"../../types\"\nimport * as ZoomableImage from \"../shared/zoomable-image\"\nimport {\n  cropImageBoundingBoxToRobotoffBoundingBox,\n  robotoffBoundingBoxToCropImageBoundingBox,\n} from \"../../utils/crop\"\nimport { EventType } from \"../../constants\"\nimport \"../shared/loading-button\"\nimport { triggerSubmit } from \"../../utils\"\nimport \"../shared/text-corrector-highlight\"\n\n@customElement(\"robotoff-ingredient-detection-form\")\n@localized()\nexport class RobotoffIngredientDetectionForm extends LitElement {\n  static override styles = [\n    css`\n      .button-container {\n        display: flex;\n        flex-wrap: wrap;\n        justify-content: center;\n        gap: 0.5rem;\n        margin-top: 1.5rem;\n        margin-bottom: 0.5rem;\n        width: 100%;\n      }\n      .button-container loading-button {\n        flex-grow: 1;\n        flex-shrink: 0;\n      }\n\n      .crop-button-container {\n        display: flex;\n        margin-top: 0.5rem;\n        margin-bottom: 0.5rem;\n      }\n    `,\n    FLEX,\n  ]\n\n  /**\n   * The form element\n   * @type {HTMLFormElement}\n   */\n  @query(\"form\")\n  form?: HTMLFormElement\n\n  /**\n   * Indicates which annotation answer is currently being sent by the form, if any.\n   * @type {AnnotationAnswer}\n   */\n  @property({ type: Number, reflect: true })\n  loading?: AnnotationAnswer\n\n  /**\n   * The insight to display and interact with\n   * @type {IngredientDetectionInsight}\n   */\n  @property({ type: Object, reflect: true })\n  insight?: IngredientDetectionInsight\n\n  /**\n   * Current crop mode\n   * @type {ZoomableImage.CropMode}\n   */\n  @state()\n  cropMode: ZoomableImage.CropMode = ZoomableImage.CropMode.CROP_READ\n\n  /**\n   * The loaded image element\n   * @type {HTMLImageElement|undefined}\n   */\n  @state()\n  image?: HTMLImageElement\n\n  /**\n   * The annotation data for the current insight\n   * @type {Partial<IngredientDetectionAnnotationData>}\n   */\n  @state()\n  data: Partial<IngredientDetectionAnnotationData> = {\n    annotation: undefined,\n    bounding_box: undefined,\n    rotation: undefined,\n  }\n\n  /**\n   * Whether the ingredients are being edited\n   * @type {boolean}\n   */\n  @state()\n  isEditingIngredients = false\n\n  private imageSize = { height: \"500px\", width: \"100%\" }\n\n  /**\n   * Determines if the form is in a loading state\n   * @returns {boolean} True if loading, false otherwise\n   */\n  get isLoading() {\n    return Boolean(this.loading) || this.cropMode === ZoomableImage.CropMode.CROP\n  }\n\n  /**\n   * Gets the bounding box for the image crop\n   * @returns {Object} The bounding box coordinates and dimensions\n   */\n  get boundingBox() {\n    const robotoffBoundingBox = this.data?.bounding_box\n    const boundingBox =\n      robotoffBoundingBox && this.image\n        ? robotoffBoundingBoxToCropImageBoundingBox(\n            robotoffBoundingBox,\n            this.image.naturalWidth,\n            this.image.naturalHeight\n          )\n        : { x: 0, y: 0, width: 0, height: 0 }\n\n    return boundingBox\n  }\n\n  /**\n   * Override the attributeChangedCallback to load the image and data when the insight changes\n   * @param {string} name - The name of the attribute that changed\n   * @param {string} oldval - The old value of the attribute\n   * @param {string} newval - The new value of the attribute\n   */\n  override attributeChangedCallback(name: string, oldval: string, newval: string) {\n    super.attributeChangedCallback(name, oldval, newval)\n    if (name === \"insight\") {\n      this.onInsightChange()\n    }\n  }\n\n  /**\n   * Handles changes to the insight property\n   * Loads the image and resets the form data when the insight changes\n   */\n  onInsightChange() {\n    // Load the image when the insight changes\n    this.loadImage()\n\n    this.isEditingIngredients = false\n    this.cropMode = ZoomableImage.CropMode.CROP_READ\n    // Set the data from the insight\n    this.data = {\n      bounding_box: this.insight?.data.bounding_box,\n      annotation: this.insight?.data.text,\n      rotation: this.insight?.data.rotation,\n    }\n  }\n\n  /**\n   * Lifecycle method called when the component is connected to the DOM\n   * Ensures the image is loaded when the component is connected\n   */\n  override connectedCallback() {\n    super.connectedCallback()\n    // Ensure the image is loaded when the component is connected to the DOM\n    this.loadImage()\n  }\n\n  /**\n   * Loads the image from the insight's source image URL\n   * Sets up the image element and triggers a re-render when loaded\n   */\n  async loadImage() {\n    this.image = undefined\n    if (!this.insight?.source_image) {\n      return\n    }\n    this.image = new Image()\n    this.image.onload = () => {\n      this.requestUpdate()\n    }\n    this.image.src = getRobotoffImageUrl(this.insight.source_image!)\n  }\n\n  /**\n   * Renders the crop answer buttons\n   * @returns {TemplateResult}\n   */\n  renderCropAnswerButtons() {\n    return html`\n      <div class=\"flex flex-col align-center\">\n        <div class=\"button-container\">\n          <loading-button\n            css-classes=\"button success-button\"\n            type=\"submit\"\n            .loading=${this.loading === AnnotationAnswer.ACCEPT ||\n            this.loading === AnnotationAnswer.ACCEPT_AND_ADD_DATA}\n            .disabled=${this.isLoading}\n            @click=\"${() => triggerSubmit(this.form!)}\"\n            label=\"${msg(\"Validate\")}\"\n          ></loading-button>\n          <loading-button\n            css-classes=\"button danger-button\"\n            .loading=${this.loading === AnnotationAnswer.REFUSE}\n            .disabled=${this.isLoading}\n            @click=\"${() => this.answer(AnnotationAnswer.REFUSE)}\"\n            label=\"${msg(\"Invalidate\")}\"\n          ></loading-button>\n          <loading-button\n            css-classes=\"button white-button\"\n            .loading=${this.loading === AnnotationAnswer.SKIP}\n            .disabled=${this.isLoading}\n            @click=\"${() => this.answer(AnnotationAnswer.SKIP)}\"\n            label=\"${msg(\"Skip\")}\"\n          ></loading-button>\n        </div>\n      </div>\n    `\n  }\n\n  /**\n   * Renders the component\n   * @returns {TemplateResult}\n   */\n  override render() {\n    if (!this.insight) {\n      return html`<div>No insight provided</div>`\n    }\n\n    return this.renderInsight(this.insight)\n  }\n\n  /**\n   * Handles form submission\n   * Determines the appropriate answer based on whether changes were made\n   * @param {Event} event - The submit event\n   */\n  onSubmit(event: Event) {\n    event.preventDefault()\n    event.stopPropagation()\n\n    const { text, bounding_box, rotation } = this.insight!.data\n    const hasChanges =\n      this.data.annotation !== text ||\n      this.data.bounding_box !== bounding_box ||\n      this.data.rotation !== rotation\n\n    if (hasChanges) {\n      this.answer(AnnotationAnswer.ACCEPT_AND_ADD_DATA, {\n        annotation: this.data.annotation ?? text,\n        bounding_box: this.data.bounding_box ?? bounding_box,\n        rotation: this.data.rotation ?? rotation,\n      })\n    } else {\n      this.answer(AnnotationAnswer.ACCEPT)\n    }\n  }\n\n  /**\n   * Renders the crop mode buttons\n   * @returns {TemplateResult} The template for the crop buttons\n   */\n  renderCropButtons() {\n    if (this.cropMode === ZoomableImage.CropMode.CROP) {\n      const isLoading = Boolean(this.loading)\n      return html`\n            <loading-button\n              css-classes=\"button cappucino-button\"\n              .disabled=${isLoading}\n              @click=\"${this.toggleCropMode}\"\n              label=\"${msg(\"Cancel crop\")}\"\n            ></loading-button>\n          </div>\n        `\n    }\n    return html`\n      <loading-button\n        css-classes=\"button chocolate-button\"\n        .disabled=${this.isLoading}\n        @click=\"${this.toggleCropMode}\"\n        label=\"${msg(\"I'll propose a better crop\")}\"\n      ></loading-button>\n    `\n  }\n\n  /**\n   * Toggles the ingredients editing mode\n   */\n  toggleEditIngredients() {\n    this.isEditingIngredients = !this.isEditingIngredients\n  }\n\n  onAnnotationChange(e: InputEvent) {\n    const textarea = e.target as HTMLTextAreaElement\n    this.data.annotation = textarea.value\n  }\n  /**\n   * Renders the ingredients editing interface\n   * @param {IngredientDetectionInsight} insight - The current insight\n   * @returns {TemplateResult} The template for the ingredients section\n   */\n  renderEditIngredients(insight: IngredientDetectionInsight) {\n    let content\n    if (this.isEditingIngredients) {\n      content = html`<text-corrector-highlight\n        heading-level=\"h4\"\n        original=${insight.data.text}\n        .value=${this.data.annotation}\n        @input=\"${this.onAnnotationChange}\"\n      ></text-corrector-highlight>`\n    } else {\n      content = html`\n        <p>${insight.data.text}</p>\n        <loading-button\n          css-classes=\"button chocolate-button\"\n          .disabled=${this.isLoading}\n          @click=\"${this.toggleEditIngredients}\"\n          label=\"${msg(\"I'll edit the ingredients\")}\"\n        ></loading-button>\n      `\n    }\n\n    return html`\n      <h3>${msg(\"Ingredients :\")}</h3>\n      ${content}\n    `\n  }\n\n  /**\n   * Handles the rotate event from the zoomable-image component\n   * @param {CustomEvent<{ rotation: number }>} event - The rotate event\n   * @returns {void}\n   */\n  onRotate(event: CustomEvent<{ rotation: number }>) {\n    this.data.rotation = event.detail.rotation\n  }\n\n  /**\n   * Renders an ingredient detection insight\n   * @param {IngredientDetectionInsight} insight - The insight to render\n   * @returns {TemplateResult}\n   */\n  private renderInsight(insight: IngredientDetectionInsight) {\n    if (!insight.source_image) {\n      return nothing\n    }\n    const imgUrl = getRobotoffImageUrl(insight.source_image)\n    const rotation = this.insight?.data.rotation ?? 0\n\n    return html`\n      <form @submit=${this.onSubmit}>\n        <div>\n          <zoomable-image\n            src=${imgUrl}\n            .size=${this.imageSize}\n            crop-mode=${this.cropMode}\n            .boundingBox=${this.boundingBox}\n            show-buttons\n            @submit=${this.onCropSave}\n            .rotation=${rotation}\n            @rotate=${this.onRotate}\n          ></zoomable-image>\n          <div class=\"crop-button-container\">${this.renderCropButtons()}</div>\n        </div>\n        <div>${this.renderEditIngredients(insight)}</div>\n        ${this.renderCropAnswerButtons()}\n      </form>\n    `\n  }\n\n  /**\n   * Toggles the crop mode between read and edit modes\n   */\n  toggleCropMode() {\n    this.cropMode =\n      this.cropMode === ZoomableImage.CropMode.CROP\n        ? ZoomableImage.CropMode.CROP_READ\n        : ZoomableImage.CropMode.CROP\n  }\n\n  /**\n   * Updates the annotation data with new values\n   * @param {Partial<IngredientDetectionAnnotationData>} data - The data to update\n   */\n  updateData(data: Partial<IngredientDetectionAnnotationData>) {\n    this.data = { ...this.data, ...data }\n  }\n  /**\n   * Handles the crop save event\n   * @param {CustomEvent<CropResult>} event - The crop save event\n   */\n  onCropSave(event: CustomEvent<CropResult>) {\n    if (!this.image) {\n      return\n    }\n    const robotoffBoundingBox = cropImageBoundingBoxToRobotoffBoundingBox(\n      event.detail.newBoundingBox,\n      this.image.naturalWidth,\n      this.image.naturalHeight\n    )\n\n    this.updateData({ bounding_box: robotoffBoundingBox, rotation: event.detail.rotation })\n    this.toggleCropMode()\n  }\n\n  /**\n   * Handles the answer event\n   * @param {AnnotationAnswer} value - The answer value\n   * @param {IngredientDetectionAnnotationData} [data] - The annotation data for the answer\n   */\n  async answer(value: AnnotationAnswer, data?: IngredientDetectionAnnotationData) {\n    this.isEditingIngredients = false\n    // Emit the submit event with the answer details\n    this.dispatchEvent(\n      new CustomEvent(EventType.SUBMIT, {\n        bubbles: true,\n        composed: true,\n        detail: {\n          insightId: this.insight!.id,\n          value,\n          data,\n        },\n      })\n    )\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"robotoff-ingredient-detection-form\": RobotoffIngredientDetectionForm\n  }\n}\n","/**\n * RobotoffIngredientDetection Component\n *\n * This component is responsible for managing ingredient detection insights\n * for the Robotoff application. It fetches ingredient detection insights\n * and delegates the form interaction to the robotoff-ingredient-detection-form component.\n *\n * @element robotoff-ingredient-detection\n */\n\nimport { LitElement, css, html, nothing } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { AnnotationAnswer, type IngredientDetectionInsight } from \"../../types/robotoff\"\nimport { Task } from \"@lit/task\"\nimport { localized, msg } from \"@lit/localize\"\nimport \"../shared/loader\"\nimport {\n  fetchIngredientsDetectionInsights,\n  ingredientDetectionInsights,\n} from \"../../signals/ingredient-detection\"\nimport robotoff from \"../../api/robotoff\"\nimport \"./robotoff-ingredient-detection-form\"\nimport { LoadingWithTimeoutMixin } from \"../../mixins/loading-with-timeout-mixin\"\nimport { LanguageCodesMixin } from \"../../mixins/language-codes-mixin\"\nimport { EventType, EventState } from \"../../constants\"\nimport type { RobotoffIngredientsStateEventDetail } from \"../../types/ingredient-spellcheck\"\nimport { DisplayProductLinkMixin } from \"../../mixins/display-product-link-mixin\"\n\n/**\n * RobotoffIngredientDetection Component\n *\n * This component is responsible for managing ingredient detection insights\n * for the Robotoff application. It fetches ingredient detection insights\n * and delegates the form interaction to the robotoff-ingredient-detection-form component.\n *\n * @element robotoff-ingredient-detection\n * @fires robotoff-ingredients-state - Indicates the state of the ingredient detection process.\n */\n@customElement(\"robotoff-ingredient-detection\")\n@localized()\nexport class RobotoffIngredientDetection extends DisplayProductLinkMixin(\n  LanguageCodesMixin(LoadingWithTimeoutMixin(LitElement, undefined as AnnotationAnswer | undefined))\n) {\n  static override styles = [\n    css`\n      :host {\n        display: block;\n        max-width: 800px;\n        width: 100%;\n      }\n    `,\n  ]\n\n  /**\n   * Number of predictions to fetch\n   * @type {number}\n   */\n  @property({ type: Number })\n  count: number = 100\n\n  /**\n   * Current page number for pagination\n   * @type {number}\n   */\n  @property({ type: Number })\n  page: number = 1\n\n  /**\n   * Barcode of the product\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"product-code\", reflect: true })\n  productCode?: string = undefined\n\n  /**\n   * Current index of the insight\n   * @type {number}\n   */\n  @state()\n  index = 0\n\n  /**\n   * List of insight ids\n   * @type {string[]}\n   */\n  @state()\n  insightIds: string[] = []\n\n  /**\n   * Dispatches an ingredient detection state event with the provided detail.\n   * @param {RobotoffIngredientsStateEventDetail} detail - The detail of the event.\n   */\n  dispatchIngredientDetectionStateEvent(detail: RobotoffIngredientsStateEventDetail) {\n    this.dispatchEvent(\n      new CustomEvent<RobotoffIngredientsStateEventDetail>(EventType.INGREDIENT_DETECTION_STATE, {\n        bubbles: true,\n        composed: true,\n        detail: {\n          productCode: this.productCode,\n          ...detail,\n        },\n      })\n    )\n  }\n\n  /**\n   * Gets all insights by mapping insight IDs to their corresponding insight objects\n   * @returns {IngredientDetectionInsight[]} Array of insight objects\n   */\n  get insights() {\n    return this.insightIds.map((id) => ingredientDetectionInsights.getItem(id))\n  }\n\n  /**\n   * Gets the current insight based on the current index\n   * @returns {IngredientDetectionInsight|undefined} The current insight or undefined if not found\n   */\n  get currentInsight() {\n    return this.insights[this.index]\n  }\n\n  /**\n   * Task for fetching ingredient detection insights\n   * Handles the asynchronous fetching of insights and updates the component state\n   */\n  private insightsTask = new Task(this, {\n    task: async ([count, page, productCode], {}) => {\n      this.insightIds = []\n\n      const response = await fetchIngredientsDetectionInsights(productCode, {\n        count,\n        page,\n        // use _languageCodes instead of languageCodes to get fallback language\n        lc: this._languageCodes,\n      })\n      this.insightIds = response.map((insight) => insight.id)\n      this.dispatchIngredientDetectionStateEvent({\n        state: this.insightIds.length ? EventState.HAS_DATA : EventState.NO_DATA,\n      })\n      this.setIndex(0)\n      return response\n    },\n    // use languageCode to avoid fallback language\n    args: () => [this.count, this.page, this.productCode, ...this._languageCodes],\n  })\n\n  /**\n   * Sets the current index and updates the component state\n   * @param {number} index - The index to set\n   */\n  async setIndex(index: number) {\n    this.index = index\n  }\n\n  /**\n   * Renders the component\n   * @returns {TemplateResult}\n   */\n  override render() {\n    return this.insightsTask.render({\n      pending: () => html`<off-wc-loader></off-wc-loader>`,\n      complete: () => {\n        const insight = this.currentInsight\n\n        if (!insight) {\n          return nothing\n        }\n\n        return this.renderInsight(insight)\n      },\n      error: (error: unknown) => html`<p>Error: ${String(error)}</p>`,\n    })\n  }\n\n  /**\n   * Renders an ingredient detection insight\n   * @param {IngredientDetectionInsight} insight - The insight to render\n   * @returns {TemplateResult}\n   */\n  private renderInsight(insight: IngredientDetectionInsight) {\n    return html`\n      <div>\n        <h2>${msg(\"Help us for ingredients\")}</h2>\n        <p>${msg(\"Help us validate the ingredient list of the product.\")}</p>\n        ${this.renderProductLink(insight.barcode)}\n        <robotoff-ingredient-detection-form\n          .insight=${insight}\n          .loading=${this.loading}\n          @submit=${this.onFormSubmit}\n        ></robotoff-ingredient-detection-form>\n      </div>\n    `\n  }\n\n  /**\n   * Handles the form submit event from the form component\n   * @param {CustomEvent} event - The submit event\n   */\n  async onFormSubmit(event: CustomEvent) {\n    const { insightId, value, data } = event.detail\n\n    this.showLoading(value)\n    await robotoff.annotateIngredientDetection(insightId, value, data)\n    await this.hideLoading()\n    this.dispatchIngredientDetectionStateEvent({\n      state: EventState.ANNOTATED,\n    })\n    const newIndex = this.index + 1\n    this.setIndex(newIndex)\n    if (newIndex >= this.insights.length) {\n      this.dispatchIngredientDetectionStateEvent({\n        state: EventState.FINISHED,\n      })\n    }\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"robotoff-ingredient-detection\": RobotoffIngredientDetection\n  }\n}\n","import { LitElement, html, nothing } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { EventState, EventType, RobotoffContributionType } from \"../../constants\"\nimport type { BasicStateEventDetail } from \"../../types\"\nimport { localized, msg } from \"@lit/localize\"\nimport { IS_HIDDEN } from \"../../styles/utils\"\nimport { classMap } from \"lit/directives/class-map.js\"\n\nimport \"../shared/modal\"\nimport \"../robotoff-ingredient-spellcheck/robotoff-ingredient-spellcheck\"\nimport \"../robotoff-nutrient-extraction/robotoff-nutrient-extraction\"\nimport \"../robotoff-ingredient-detection/robotoff-ingredient-detection\"\nimport \"../robotoff-question/robotoff-question\"\n\nenum MessageType {\n  SUCCESS = \"success\",\n  ANNOTATION_SUCCESS = \"annotation-success\",\n}\n\n/**\n * The `robotoff-modal` component is a web component that displays a modal for contributing to product information.\n * It handles different types of contributions (ingredients, nutrients, and questions) and manages the modal's state.\n *\n * @fires success - Dispatched when a contribution is successfully made.\n * @fires close - Dispatched when the modal is closed.\n *\n * @slot success-message - The slot for the success message.\n * @slot annotated-message - The slot for the annotated message.\n *\n * @example\n * ```html\n * <robotoff-modal product-code=\"123456789\" robotoff-contribution-type=\"ingredients\"></robotoff-modal>\n * ```\n */\n\n@customElement(\"robotoff-modal\")\n@localized()\nexport class RobotoffModal extends LitElement {\n  static override styles = [IS_HIDDEN]\n\n  /**\n   * The type of contribution being made.\n   */\n  @property({ type: String, attribute: \"robotoff-contribution-type\" })\n  robotoffContributionType?: RobotoffContributionType\n\n  /**\n   * The product code for which the contribution is being made.\n   */\n  @property({ type: String, attribute: \"product-code\" })\n  productCode: string = \"\"\n\n  /**\n   * Indicates whether the modal is in a loading state.\n   */\n  @state()\n  isLoading = false\n\n  /**\n   * Indicates whether the success message should be shown.\n   */\n  @state()\n  showMessage?: MessageType\n\n  /**\n   * Returns whether the modal is open based on the `robotoffContributionType`.\n   */\n  get isOpen() {\n    return Boolean(this.robotoffContributionType)\n  }\n\n  /**\n   * Dispatches a success event when a contribution is successfully made (or skipped).\n   * @param {RobotoffContributionType} type - The type of contribution.\n   */\n  sendSuccessEvent(type: RobotoffContributionType) {\n    this.dispatchEvent(\n      new CustomEvent(EventType.SUCCESS, {\n        bubbles: true,\n        composed: true,\n        detail: {\n          type: type,\n        },\n      })\n    )\n  }\n\n  /**\n   * Handles the annotated event (meaning all insight have been processed)\n   * by showing a success message and dispatching a success event.\n   */\n  onFinished() {\n    const robotoffContributionType = this.robotoffContributionType!\n    this.showMessage = MessageType.SUCCESS\n    setTimeout(() => {\n      if (this.showMessage === MessageType.SUCCESS) {\n        this.showMessage = undefined\n      }\n      this.sendSuccessEvent(robotoffContributionType)\n    }, 1000)\n  }\n\n  /**\n   * Handles the annotated event (meaning one insight has been processed)\n   * by showing a success message.\n   */\n  onAnnotated() {\n    this.showMessage = MessageType.ANNOTATION_SUCCESS\n    setTimeout(() => {\n      if (this.showMessage === MessageType.ANNOTATION_SUCCESS) {\n        this.showMessage = undefined\n      }\n    }, 1000)\n  }\n\n  /**\n   * Handles state changes from child components.\n   * @param {CustomEvent<BasicStateEventDetail>} event - The state change event.\n   */\n  onStateChange(event: CustomEvent<BasicStateEventDetail>) {\n    switch (event.detail.state) {\n      // When all insight is annotated, we show a success message\n      case EventState.FINISHED:\n        this.onFinished()\n        break\n      case EventState.ANNOTATED:\n        this.onAnnotated()\n        break\n      case EventState.LOADING:\n        this.isLoading = true\n        break\n      case EventState.HAS_DATA:\n        this.isLoading = false\n        break\n      case EventState.NO_DATA:\n        this.isLoading = false\n        // Send success event if no data to display because we don't want to show the modal again\n        this.sendSuccessEvent(this.robotoffContributionType!)\n        break\n    }\n  }\n\n  /**\n   * Renders the modal content based on the `robotoffContributionType`.\n   */\n  renderModalContent() {\n    switch (this.robotoffContributionType) {\n      case RobotoffContributionType.INGREDIENT_SPELLCHECK:\n        return html`<robotoff-ingredient-spellcheck\n          product-code=\"${this.productCode}\"\n          @ingredients-state=\"${this.onStateChange}\"\n        ></robotoff-ingredient-spellcheck>`\n      case RobotoffContributionType.NUTRIENT_EXTRACTION:\n        return html`<robotoff-nutrient-extraction\n          product-code=\"${this.productCode}\"\n          @nutrient-state=\"${this.onStateChange}\"\n        ></robotoff-nutrient-extraction>`\n      case RobotoffContributionType.INGREDIENT_DETECTION:\n        return html`<robotoff-ingredient-detection\n          product-code=\"${this.productCode}\"\n          @ingredient-detection-state=\"${this.onStateChange}\"\n        ></robotoff-ingredient-detection>`\n      case RobotoffContributionType.QUESTIONS:\n        return html`<robotoff-question\n          product-code=\"${this.productCode}\"\n          @question-state=\"${this.onStateChange}\"\n        ></robotoff-question>`\n    }\n    return nothing\n  }\n\n  /**\n   * Closes the modal and dispatches a close event.\n   */\n  closeModal() {\n    this.dispatchEvent(new CustomEvent(EventType.CLOSE))\n  }\n\n  /**\n   * Renders the success message.\n   */\n  renderMessage() {\n    if (!this.showMessage) return nothing\n    switch (this.showMessage) {\n      case MessageType.SUCCESS:\n        return html`<slot name=\"success-message\"\n          ><div class=\"success-message\">${msg(\"Thanks for your contribution!\")}</div></slot\n        >`\n      case MessageType.ANNOTATION_SUCCESS:\n        return html`<slot name=\"annotated-message\"\n          ><div class=\"annotated-message\">\n            ${msg(\"Saved! Can you help with another one?\")}\n          </div></slot\n        >`\n    }\n    return nothing\n  }\n\n  override render() {\n    return html`\n      <modal-component\n        ?is-open=\"${this.isOpen}\"\n        ?is-loading=\"${this.isLoading}\"\n        @close=\"${this.closeModal}\"\n      >\n        ${this.renderMessage()}\n        <div class=${classMap({ \"is-hidden\": Boolean(this.showMessage) })}>\n          ${this.renderModalContent()}\n        </div>\n      </modal-component>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"robotoff-modal\": RobotoffModal\n  }\n}\n","import { LitElement, css, html, nothing } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { Task } from \"@lit/task\"\nimport { ALERT } from \"../../styles/alert.js\"\n\nimport { fetchQuestionsByProductCode } from \"../../signals/questions\"\nimport { localized, msg } from \"@lit/localize\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons.js\"\nimport { RobotoffContributionType } from \"../../constants.js\"\nimport { CONTAINER } from \"../../styles/responsive.js\"\nimport \"../robotoff-modal/robotoff-modal\"\nimport { SignalWatcher } from \"@lit-labs/signals\"\nimport robotoff from \"../../api/robotoff.js\"\nimport { InsightType } from \"../../types/robotoff.js\"\nimport { LanguageCodesMixin } from \"../../mixins/language-codes-mixin.js\"\n\n/**\n * The `robotoff-contribution-message` component is a web component that displays messages prompting users to contribute to improving product information.\n * It fetches data from various signals (ingredients, nutrients, and questions) and displays relevant messages based on the fetched data.\n *\n * @fires success - Dispatched when a contribution is successfully made.\n * @fires close - Dispatched when the modal is closed.\n *\n * @example\n * ```html\n * <robotoff-contribution-message product-code=\"123456789\"></robotoff-contribution-message>\n * ```\n */\n@customElement(\"robotoff-contribution-message\")\n@localized()\nexport class RobotoffContributionMessage extends LanguageCodesMixin(SignalWatcher(LitElement)) {\n  static override styles = [\n    ALERT,\n    CONTAINER,\n    getButtonClasses([ButtonType.White]),\n    css`\n      :host {\n        display: block;\n        width: 100%;\n      }\n      .robotoff-contribution-message.alert {\n        padding: 1rem;\n        width: 100%;\n        text-align: left;\n        box-sizing: border-box;\n      }\n      .robotoff-contribution-message p {\n        margin-top: 0;\n      }\n      .robotoff-contribution-message ul {\n        margin-bottom: 0;\n        display: flex;\n        flex-direction: column;\n        gap: 0.5rem;\n        padding-left: 0;\n        list-style-type: none;\n      }\n      .robotoff-contribution-message li {\n        text-align: left;\n      }\n    `,\n  ]\n\n  /**\n   * The product code for which the contribution messages are displayed.\n   */\n  @property({ type: String, attribute: \"product-code\", reflect: true })\n  productCode = \"\"\n\n  /**\n   * Whether the user is logged in.\n   */\n  @property({\n    type: Boolean,\n    attribute: \"is-logged-in\",\n  })\n  isLoggedIn = false\n\n  /**\n   * The type of contribution being made.\n   */\n  @state()\n  robotoffContributionType?: RobotoffContributionType\n\n  /**\n   * A record indicating which messages should be shown.\n   */\n  @state()\n  showMessages: Record<RobotoffContributionType, boolean> = {\n    [RobotoffContributionType.INGREDIENT_SPELLCHECK]: false,\n    [RobotoffContributionType.NUTRIENT_EXTRACTION]: false,\n    [RobotoffContributionType.INGREDIENT_DETECTION]: false,\n    [RobotoffContributionType.QUESTIONS]: false,\n  }\n\n  /**\n   * Returns the messages to be displayed based on the `showMessages` state.\n   *\n   * This correspond to the various type of contribution.\n   * Each one is materialized as a button to the user.\n   */\n  get messagesToShow() {\n    const items: {\n      type: RobotoffContributionType\n      message: string\n    }[] = [\n      {\n        type: RobotoffContributionType.QUESTIONS,\n        message: msg(\"Answer questions about the product.\"),\n      },\n      {\n        type: RobotoffContributionType.INGREDIENT_SPELLCHECK,\n        message: msg(\"Help us correct the spelling of ingredients.\"),\n      },\n      {\n        type: RobotoffContributionType.NUTRIENT_EXTRACTION,\n        message: msg(\"Help us correct the nutritional information.\"),\n      },\n      {\n        type: RobotoffContributionType.INGREDIENT_DETECTION,\n        message: msg(\"Help us correct the ingredient detection\"),\n      },\n    ].filter((item) => this.showMessages[item.type])\n\n    return items\n  }\n\n  /**\n   * A task that fetches data for the component.\n   * It refreshes when the `productCode` property changes.\n   * It computes this.showMessages and returns the fetched insights\n   * It fetches from robotoff : spellcheck insights, nutrient insights, and questions for the product.\n   */\n  private _fetchDataTask = new Task(this, {\n    task: async ([productCode]) => {\n      console.log(\"Fetching data for product code\", productCode, this._languageCodes)\n      this.showMessages = {\n        [RobotoffContributionType.QUESTIONS]: false,\n        [RobotoffContributionType.INGREDIENT_SPELLCHECK]: false,\n        [RobotoffContributionType.NUTRIENT_EXTRACTION]: false,\n        [RobotoffContributionType.INGREDIENT_DETECTION]: false,\n      }\n\n      // Check if it need contributions. If not, don't show the message. If request fails, hide the message but do not crash all requests\n      const [questions, insights] = await Promise.allSettled([\n        fetchQuestionsByProductCode(productCode),\n        ...(this.isLoggedIn\n          ? [\n              robotoff.fetchRobotoffContributionMessageInsights({\n                barcode: productCode,\n                lc: this._languageCodes,\n              }),\n            ]\n          : []),\n      ])\n      const insightValues = {\n        [InsightType.ingredient_spellcheck]: false,\n        [InsightType.nutrient_extraction]: false,\n        [InsightType.ingredient_detection]: false,\n      }\n\n      if (insights?.status === \"fulfilled\") {\n        for (const insight of insights.value) {\n          insightValues[insight.type as InsightType] = true\n          // If all insights are true, break the loop\n          if (Object.values(insightValues).every((value) => value)) {\n            break\n          }\n        }\n      }\n\n      this.showMessages = {\n        questions: questions?.status === \"fulfilled\" && questions.value.length > 0,\n        ...insightValues,\n      }\n    },\n    args: () => [this.productCode, ...this._languageCodes],\n  })\n\n  /**\n   * Opens the modal for the specified contribution type.\n   * @param {RobotoffContributionType} type - The type of contribution.\n   */\n  openModal(type: RobotoffContributionType) {\n    this.robotoffContributionType = type\n  }\n  /**\n   * Closes the modal.\n   */\n  closeModal() {\n    this.robotoffContributionType = undefined\n  }\n  /**\n   * Handles the save event when a contribution is made.\n   * @param {CustomEvent<{ type: RobotoffContributionType }>} event - The event containing the contribution type.\n   */\n  onSave(event: CustomEvent<{ type: RobotoffContributionType }>) {\n    this.showMessages[event.detail.type!] = false\n    this.closeModal()\n    this.requestUpdate()\n  }\n\n  /**\n   * Renders the component.\n   * @returns {TemplateResult} The rendered template.\n   */\n  override render() {\n    return this._fetchDataTask.render({\n      complete: () => {\n        const messagesToShow = this.messagesToShow\n\n        if (!messagesToShow.length) {\n          return nothing\n        }\n        return html` <div>\n          <robotoff-modal\n            product-code=${this.productCode}\n            .robotoffContributionType=${this.robotoffContributionType}\n            @close=${this.closeModal}\n            @success=${this.onSave}\n          ></robotoff-modal>\n          <div class=\"robotoff-contribution-message alert info\">\n            <div class=\"container\">\n              <p>\n                ${msg(\n                  \"Hey! You can help us improve the product information by answering the following parts:\"\n                )}\n              </p>\n              <ul>\n                ${this.messagesToShow.map(\n                  (item) =>\n                    html`<li>\n                      <button\n                        class=\"button white-button small\"\n                        @click=${() => this.openModal(item.type)}\n                      >\n                        ${item.message}\n                      </button>\n                    </li>`\n                )}\n              </ul>\n            </div>\n          </div>\n        </div>`\n      },\n      pending: () => nothing,\n      error: () => nothing,\n    })\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"robotoff-contribution-message\": RobotoffContributionMessage\n  }\n}\n","import type { KnowledgePanelsData } from \"../types/knowledge-panel\"\n\n/**\n * Fetches knowledge panels data from specified URL and extracts data at the given path\n * @param url The URL to fetch knowledge panels from\n * @param path The path to the knowledge panels in the JSON response\n * @returns The knowledge panels data\n */\nexport const fetchKnowledgePanels = async (\n  url: string,\n  path: string\n): Promise<KnowledgePanelsData> => {\n  try {\n    const response = await fetch(url)\n\n    if (!response.ok) {\n      throw new Error(`Failed to fetch: ${response.statusText}`)\n    }\n\n    const data = await response.json()\n    console.log(\"Raw API response:\", data)\n\n    // Navigate through the path to find the knowledge panels\n    let result = data\n    const pathParts = path.split(\".\")\n\n    for (const part of pathParts) {\n      console.log(`Navigating to \"${part}\"`, result)\n      if (result && typeof result === \"object\" && part in result) {\n        result = result[part]\n      } else {\n        throw new Error(`Path \"${path}\" not found in the response data`)\n      }\n    }\n\n    console.log(\"Final knowledge panels result:\", result)\n    return result as KnowledgePanelsData\n  } catch (error) {\n    console.error(\"Error fetching knowledge panels:\", error)\n    throw error\n  }\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type { KnowledgePanelElement } from \"../../../types/knowledge-panel\"\nimport { sanitizeHtml } from \"../../../utils/html\"\n\n/**\n * Action element renderer component\n *\n * @element action-element-renderer\n */\n@customElement(\"action-element-renderer\")\nexport class ActionElementRenderer extends LitElement {\n  static override styles = css`\n    .action {\n      width: 100%;\n      margin: 1rem 0;\n      padding: 1rem;\n      background-color: #f8f9fa;\n      border-radius: 22px;\n      border: 1px solid #e8e8e8;\n      text-align: left;\n      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03);\n    }\n\n    .action small {\n      width: 100%;\n      display: block;\n      margin-top: 0.5rem;\n      font-style: italic;\n      font-size: 0.85rem;\n      word-wrap: break-word;\n      line-height: 1.5;\n    }\n\n    .button {\n      display: inline-block;\n      font-weight: 500;\n      text-align: center;\n      vertical-align: middle;\n      cursor: pointer;\n      padding: 0.375rem 0.75rem;\n      font-size: 1rem;\n      line-height: 1.5;\n      border-radius: 0.25rem;\n      transition:\n        color 0.15s ease-in-out,\n        background-color 0.15s ease-in-out,\n        border-color 0.15s ease-in-out,\n        box-shadow 0.15s ease-in-out;\n    }\n\n    .chocolate-button {\n      color: #fff;\n      background-color: #7d5437;\n      border-color: #6a4730;\n    }\n\n    .chocolate-button:hover {\n      color: #fff;\n      background-color: #60412b;\n      border-color: #4d3422;\n    }\n  `\n\n  @property({ type: Object })\n  element?: KnowledgePanelElement\n\n  override render(): TemplateResult {\n    if (!this.element) {\n      return html``\n    }\n\n    const actionElement = this.element.action_element\n    if (!actionElement) {\n      return html``\n    }\n\n    const actionText = (actionElement as any).action_text || \"Default Action\"\n    const actionDescription = (actionElement as any).description || \"\"\n    const sanitizedHTML = sanitizeHtml(actionElement.html || \"\")\n\n    return html`\n      <div class=\"action\">\n        <div>${sanitizedHTML}</div>\n        <button class=\"button chocolate-button\" disabled>${actionText}</button>\n        ${actionDescription ? html`<small>${actionDescription}</small>` : \"\"}\n        <small>(Actions are displayed but not functional in this version)</small>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"action-element-renderer\": ActionElementRenderer\n  }\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type { KnowledgePanelElement } from \"../../../types/knowledge-panel\"\nimport { sanitizeHtml } from \"../../../utils/html\"\n\n/**\n * Text element renderer component\n *\n * @element text-element-renderer\n */\n@customElement(\"text-element-renderer\")\nexport class TextElementRenderer extends LitElement {\n  static override styles = css`\n    .text_element {\n      width: 100%;\n      margin-bottom: 0.85rem;\n      line-height: 1.6;\n      text-align: left;\n      word-wrap: break-word;\n      overflow-wrap: break-word;\n      color: #333;\n    }\n\n    ul {\n      padding-left: 1.2rem;\n    }\n\n    p {\n      margin-top: 0;\n      margin-bottom: 0.85rem;\n    }\n  `\n\n  @property({ type: Object })\n  element?: KnowledgePanelElement\n\n  override render(): TemplateResult {\n    const textContent =\n      this.element?.text_element?.html ||\n      this.element?.text_element?.text ||\n      this.element?.text ||\n      \"\"\n\n    // Sanitize the HTML first\n    const sanitizedContent = sanitizeHtml(textContent)\n\n    // Then use it with unsafeHTML\n    return html`<div class=\"text_element\">${sanitizedContent}</div>`\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"text-element-renderer\": TextElementRenderer\n  }\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type {\n  KnowledgePanelElement,\n  TableColumn,\n  TableRow,\n  TableCell,\n  TableElement,\n} from \"../../../types/knowledge-panel\"\nimport \"../../../utils/knowledge-panels/heading-utils\" // Import heading renderer component\nimport { sanitizeHtml } from \"../../../utils/html\"\n\n/**\n * Table element renderer component\n *\n * @element table-element-renderer\n */\n@customElement(\"table-element-renderer\")\nexport class TableElementRenderer extends LitElement {\n  static override styles = css`\n    .table_element {\n      width: 100%;\n      overflow-x: auto;\n      margin-bottom: 1.25rem;\n      border-radius: 20px;\n      /*box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);*/\n    }\n\n    .table_element table {\n      width: 100%;\n      border-collapse: separate;\n      border-spacing: 0;\n      margin-bottom: 0.5rem;\n      text-align: left;\n      border: 1px solid #e6e6e6;\n      border-radius: 20px;\n      overflow: hidden;\n    }\n\n    .table_element th,\n    .table_element td {\n      border: 1px solid #e6e6e6;\n      padding: 0.75rem;\n      text-align: left;\n    }\n\n    .table_element th {\n      background-color: #f8f9fa;\n      font-weight: 600;\n    }\n\n    .table_element tr:nth-child(even) {\n      background-color: #fcfcfc;\n    }\n\n    .table_element tr:hover {\n      background-color: #f7f7f7;\n    }\n  `\n\n  @property({ type: Object })\n  element?: KnowledgePanelElement\n\n  @property({ type: String })\n  headingLevel = \"h3\"\n\n  override render(): TemplateResult {\n    if (!this.element) {\n      return html`<slot name=\"error\">Missing element data</slot>`\n    }\n\n    const tableData = this.element.table_element || ({} as TableElement)\n\n    if (!tableData) {\n      console.error(\"Invalid table element - missing table_element:\", this.element)\n      return html`<slot name=\"error\">Invalid table format</slot>`\n    }\n\n    const columns = tableData.columns || []\n    const rows = tableData.rows || []\n\n    if (!Array.isArray(columns) || !Array.isArray(rows)) {\n      console.error(\"Invalid table structure:\", tableData)\n      return html`<slot name=\"error\">Invalid table structure</slot>`\n    }\n\n    return html`\n      <div class=\"table_element\">\n        ${tableData.title\n          ? html`<heading-renderer\n              text=\"${tableData.title}\"\n              class-name=\"table-title\"\n              heading-level=\"${this.headingLevel}\"\n            >\n            </heading-renderer>`\n          : \"\"}\n        <table>\n          <thead>\n            <tr>\n              ${columns.map(\n                (column: TableColumn) =>\n                  html`<th>${sanitizeHtml(column.text || column.id || \"\")}</th>`\n              )}\n            </tr>\n          </thead>\n          <tbody>\n            ${rows.map(\n              (row: TableRow) => html`\n                <tr>\n                  ${(row.cells || []).map(\n                    (cell: TableCell) => html`<td>${cell.text || cell.value || \"\"}</td>`\n                  )}\n                </tr>\n              `\n            )}\n          </tbody>\n        </table>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"table-element-renderer\": TableElementRenderer\n  }\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type { KnowledgePanelElement } from \"../../../types/knowledge-panel\"\n\n/**\n * Titled text element renderer component\n *\n * @element titled-text-element-renderer\n */\n@customElement(\"titled-text-element-renderer\")\nexport class TitledTextElementRenderer extends LitElement {\n  static override styles = css`\n    .element {\n      width: 100%;\n      display: block;\n      padding-bottom: 0.85rem;\n      margin-bottom: 0.85rem;\n      border-bottom: 1px solid #f5f5f5;\n      text-align: left;\n    }\n\n    .element:last-child {\n      border-bottom: none;\n      margin-bottom: 0;\n    }\n\n    .element-title {\n      width: 100%;\n      display: block;\n      font-weight: 600;\n      margin-bottom: 0.5rem;\n      text-align: left;\n      word-wrap: break-word;\n    }\n\n    .element-value {\n      width: 100%;\n      display: block;\n      color: #444;\n      text-align: left;\n      word-wrap: break-word;\n      line-height: 1.6;\n    }\n  `\n\n  @property({ type: Object })\n  element?: KnowledgePanelElement\n\n  override render(): TemplateResult {\n    if (!this.element) {\n      return html``\n    }\n\n    return html`\n      <div class=\"element\">\n        <div class=\"element-title\">${this.element.title || \"\"}</div>\n        <div class=\"element-value\">${this.element.text || \"\"}</div>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"titled-text-element-renderer\": TitledTextElementRenderer\n  }\n}\n","import type {\n  KnowledgePanelsData,\n  KnowledgePanel,\n  KnowledgePanelElement,\n} from \"../../types/knowledge-panel\"\n\n/**\n * Extracts images from all panels\n * @param panels - The knowledge panels data\n * @returns Array of image URLs\n */\nexport function extractImages(panels: KnowledgePanelsData): string[] {\n  const nutritionImages: string[] = []\n\n  // First look for the nutrition panel\n  let nutritionPanel: KnowledgePanel | null = null\n  for (const panelId in panels) {\n    const panel = panels[panelId]\n    if (\n      panel.title === \"Nutrition\" ||\n      panel.title === \"Nutrition facts\" ||\n      panel.title_element?.title === \"Nutrition\" ||\n      panel.title_element?.title === \"Nutrition facts\"\n    ) {\n      nutritionPanel = panel\n      break\n    }\n  }\n\n  // If we found a nutrition panel, extract all images from it and all sub-panels\n  if (nutritionPanel && nutritionPanel.elements) {\n    // Process all elements in the nutrition panel\n    for (const element of nutritionPanel.elements) {\n      // Process text elements that might contain HTML with images\n      if (element.element_type === \"text\" && element.text_element?.html) {\n        const htmlContent = element.text_element.html\n        const imgRegex = /<img[^>]+src=\"([^\"]+)\"[^>]*>/g\n        let match\n        while ((match = imgRegex.exec(htmlContent)) !== null) {\n          if (match[1]) {\n            nutritionImages.push(match[1])\n          }\n        }\n      }\n\n      // Process panel group elements with images\n      if (element.element_type === \"panel_group\" && element.panel_group_element?.image) {\n        const image = element.panel_group_element.image\n        const imageUrl = image.sizes?.[\"400\"]?.url || image.sizes?.[\"full\"]?.url\n        if (imageUrl) {\n          nutritionImages.push(imageUrl)\n        }\n      }\n\n      // Check nested elements\n      if (element.elements) {\n        extractNestedImages(element.elements, nutritionImages)\n      }\n\n      // Check referenced panels\n      if (element.element_type === \"panel\" && element.panel_element?.panel_id) {\n        const referencedPanel = panels[element.panel_element.panel_id]\n        if (referencedPanel && referencedPanel.elements) {\n          extractNestedImages(referencedPanel.elements, nutritionImages)\n        }\n      }\n    }\n  }\n\n  // Look through all panels if we didn't find any nutrition images\n  if (nutritionImages.length === 0) {\n    for (const panelId in panels) {\n      const panel = panels[panelId]\n      if (panel.elements) {\n        extractNestedImages(panel.elements, nutritionImages)\n      }\n    }\n  }\n\n  console.log(\"Extracted nutrition images:\", nutritionImages)\n  return nutritionImages\n}\n\n/**\n * Helper to extract images from nested elements\n * @param elements - Array of panel elements to process\n * @param nutritionImages - Array to collect image URLs\n */\nfunction extractNestedImages(elements: KnowledgePanelElement[], nutritionImages: string[]): void {\n  for (const element of elements) {\n    // Process text elements that might contain HTML with images\n    if (element.element_type === \"text\" && element.text_element?.html) {\n      const htmlContent = element.text_element.html\n      const imgRegex = /<img[^>]+src=\"([^\"]+)\"[^>]*>/g\n      let match\n      while ((match = imgRegex.exec(htmlContent)) !== null) {\n        if (match[1]) {\n          nutritionImages.push(match[1])\n        }\n      }\n    }\n\n    // Process panel group elements with images\n    if (element.element_type === \"panel_group\" && element.panel_group_element?.image) {\n      const image = element.panel_group_element.image\n      const imageUrl = image.sizes?.[\"400\"]?.url || image.sizes?.[\"full\"]?.url\n      if (imageUrl) {\n        nutritionImages.push(imageUrl)\n      }\n    }\n\n    // Recursively process nested elements\n    if (element.elements) {\n      extractNestedImages(element.elements, nutritionImages)\n    }\n  }\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport \"../../../utils/knowledge-panels/heading-utils\" // Import heading renderer component\n\n/**\n * Panel header renderer component\n *\n * @element panel-header-renderer\n */\n@customElement(\"panel-header-renderer\")\nexport class PanelHeaderRenderer extends LitElement {\n  static override styles = css`\n    .panel-header {\n      width: 100%;\n      border-bottom: 1px solid #eeeeee;\n      padding: 1rem 1.25rem;\n      display: block;\n    }\n\n    .panel-subtitle {\n      width: 100%;\n      font-size: 0.95rem;\n      margin-top: 0.35rem;\n      text-align: left;\n      word-wrap: break-word;\n    }\n  `\n\n  @property({ type: String })\n  override title = \"\"\n\n  @property({ type: String })\n  subtitle = \"\"\n\n  @property({ type: String })\n  headingLevel = \"h3\"\n\n  override render(): TemplateResult {\n    if (!this.title) {\n      return html``\n    }\n\n    return html`\n      <div class=\"panel-header\">\n        <heading-renderer\n          text=\"${this.title}\"\n          class-name=\"panel-title\"\n          heading-level=\"${this.headingLevel}\"\n        >\n        </heading-renderer>\n        ${this.subtitle ? html`<div class=\"panel-subtitle\">${this.subtitle}</div>` : \"\"}\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"panel-header-renderer\": PanelHeaderRenderer\n  }\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\n\n/**\n * Panel group image renderer component\n *\n * @element panel-group-image-renderer\n */\n@customElement(\"panel-group-image-renderer\")\nexport class PanelGroupImageRenderer extends LitElement {\n  static override styles = css`\n    .panel-image {\n      width: 100%;\n      margin-bottom: 1.25rem;\n      text-align: left;\n    }\n\n    .panel-image img {\n      width: auto;\n      max-width: 100%;\n      height: auto;\n      border-radius: 20px;\n      border: 1px solid #efefef;\n      display: block;\n      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n    }\n\n    .panel-image-text {\n      width: 100%;\n      margin-top: 0.65rem;\n      font-size: 0.9rem;\n      line-height: 1.5;\n      text-align: left;\n      font-style: italic;\n      word-wrap: break-word;\n    }\n  `\n\n  @property({ type: Object })\n  panelGroup: any\n\n  override render(): TemplateResult {\n    if (!this.panelGroup || !this.panelGroup.image) {\n      return html``\n    }\n\n    const imageUrl =\n      this.panelGroup.image.sizes?.[\"400\"]?.url || this.panelGroup.image.sizes?.[\"full\"]?.url || \"\"\n\n    const imageAlt = this.panelGroup.image.alt || \"Panel image\"\n    const imageCaption = this.panelGroup.image.caption || this.panelGroup.image.description || \"\"\n\n    return html`\n      <div class=\"panel-image\">\n        <img src=\"${imageUrl}\" alt=\"${imageAlt}\" />\n        ${imageCaption ? html`<div class=\"panel-image-text\">${imageCaption}</div>` : html``}\n      </div>\n    `\n  }\n}\n\n/**\n * Generic image renderer component\n *\n * @element image-renderer\n */\n@customElement(\"image-renderer\")\nexport class ImageRenderer extends LitElement {\n  static override styles = css`\n    .panel-image {\n      width: 100%;\n      margin-bottom: 1.25rem;\n      text-align: left;\n    }\n\n    .panel-image img {\n      width: auto;\n      max-width: 100%;\n      height: auto;\n      border-radius: 20px;\n      border: 1px solid #efefef;\n      display: block;\n      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n    }\n\n    .panel-image-text {\n      width: 100%;\n      margin-top: 0.65rem;\n      font-size: 0.9rem;\n      line-height: 1.5;\n      text-align: left;\n      font-style: italic;\n      word-wrap: break-word;\n    }\n  `\n\n  @property({ type: String })\n  imageUrl = \"\"\n\n  @property({ type: String })\n  imageAlt = \"Image\"\n\n  @property({ type: String })\n  imageCaption = \"\"\n\n  override render(): TemplateResult {\n    if (!this.imageUrl) {\n      return html``\n    }\n\n    return html`\n      <div class=\"panel-image\">\n        <img src=\"${this.imageUrl}\" alt=\"${this.imageAlt}\" />\n        ${this.imageCaption\n          ? html`<div class=\"panel-image-text\">${this.imageCaption}</div>`\n          : html``}\n      </div>\n    `\n  }\n}\n\n/**\n * Nutrition image renderer component\n *\n * @element nutrition-image-renderer\n */\n@customElement(\"nutrition-image-renderer\")\nexport class NutritionImageRenderer extends LitElement {\n  static override styles = css`\n    :host {\n      display: block;\n    }\n\n    img {\n      width: auto;\n      max-width: 100%;\n      height: auto;\n      border-radius: 20px;\n      border: 1px solid #eee;\n      display: block;\n      margin: 0;\n    }\n\n    .panel-image-text {\n      width: 100%;\n      margin-top: 0.65rem;\n      font-size: 0.9rem;\n      line-height: 1.5;\n      text-align: left;\n      font-style: italic;\n      word-wrap: break-word;\n    }\n  `\n\n  @property({ type: String })\n  imageUrl = \"\"\n\n  @property({ type: String })\n  subtitle = \"\"\n\n  override render(): TemplateResult {\n    if (!this.imageUrl) {\n      return html``\n    }\n\n    return html`\n      <img src=\"${this.imageUrl}\" alt=\"Nutrition Information\" />\n      ${this.subtitle ? html`<div class=\"panel-image-text\">${this.subtitle}</div>` : \"\"}\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"panel-group-image-renderer\": PanelGroupImageRenderer\n    \"image-renderer\": ImageRenderer\n    \"nutrition-image-renderer\": NutritionImageRenderer\n  }\n}\n","import { LitElement, html, css, type TemplateResult, nothing } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type {\n  KnowledgePanel,\n  KnowledgePanelElement,\n  KnowledgePanelsData,\n} from \"../../../types/knowledge-panel\"\n\nimport \"../../../utils/knowledge-panels/heading-utils\"\nimport \"../../../utils/knowledge-panels/extract-images\"\n\nimport \"./render-panel-header\"\nimport \"./render-element\"\nimport \"./render-image\"\n\n/**\n * Panel renderer component\n *\n * @element panel-renderer\n */\n@customElement(\"panel-renderer\")\nexport class PanelRenderer extends LitElement {\n  static override styles = css`\n    .panel {\n      margin-bottom: 1.5rem;\n      border-radius: 16px;\n      border: 1px solid #f2d3ac;\n      background: #fff;\n      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n      border-bottom: 1px solid #f2d3ac;\n      background: #fffdfa;\n      overflow: hidden;\n      transition: box-shadow 0.15s;\n    }\n\n    summary {\n      background: #ffe9c7;\n      font-weight: bold;\n      font-size: 1.12rem;\n      cursor: pointer;\n      padding: 1rem 1rem;\n      border-bottom: 1px solid #f2d3ac;\n      outline: none;\n      user-select: none;\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n      color: #674d23;\n      transition: background 0.18s;\n    }\n\n    summary:hover {\n      background: #ffe0a6;\n    }\n\n    summary::-webkit-details-marker {\n      display: none;\n    }\n\n    .panel-size-small > details summary {\n      padding: 0.5rem 1rem;\n    }\n\n    .panel-header {\n      display: flex;\n      align-items: center;\n      gap: 2rem;\n    }\n\n    .panel-size-small .panel-header {\n      gap: 0.5rem;\n    }\n\n    .panel-icon {\n      border-radius: 4px;\n      width: 5rem;\n      height: 5rem;\n      object-fit: contain;\n    }\n\n    .panel-icon-small {\n      width: 1rem;\n      height: 1rem;\n    }\n\n    .panel-icon-medium {\n      width: 1.5rem;\n      height: 1.5rem;\n    }\n\n    .panel-icon-large {\n      width: 2.5rem;\n      height: 2.5rem;\n    }\n\n    .arrow {\n      transition: transform 0.2s;\n      margin-left: 0.5rem;\n      font-size: 1.3rem;\n    }\n    details[open] .arrow {\n      transform: rotate(90deg);\n    }\n    .panel-content {\n      padding: 1.2rem 1.3rem;\n      background: #fffdfa;\n    }\n    .panel-subtitle {\n      margin-bottom: 0.75rem;\n      font-style: italic;\n      color: #a88b56;\n    }\n  `\n  @property({ type: Object })\n  panel?: KnowledgePanel\n\n  @property({ type: Boolean })\n  frame = true\n\n  @property({ type: Object })\n  knowledgePanels: KnowledgePanelsData | null = null\n\n  @property({ type: Array })\n  nutritionImages: string[] = []\n\n  @property({ type: String })\n  headingLevel = \"h3\"\n\n  /**\n   * Checks if a panel is a nutrition panel\n   * @returns True if it's a nutrition panel\n   */\n  isNutritionPanel(): boolean {\n    if (!this.panel) return false\n\n    const title = this.panel.title_element?.title || this.panel.title || \"\"\n    return title.toLowerCase().includes(\"nutrition\") || title.toLowerCase().includes(\"nutritional\")\n  }\n\n  override render(): TemplateResult {\n    if (!this.panel) return html``\n\n    const title = this.panel.title_element?.title || this.panel.title || \"\"\n    const subtitle = this.panel.title_element?.subtitle || \"\"\n\n    const content =\n      this.panel.elements.length > 0\n        ? this.panel.elements.map(\n            (element: KnowledgePanelElement) =>\n              html`<element-renderer\n                .element=${element}\n                .knowledgePanels=${this.knowledgePanels}\n                headingLevel=${this.headingLevel}\n              ></element-renderer>`\n          )\n        : nothing\n\n    const icon = this.panel.title_element?.icon_url\n\n    if (!this.frame || this.panel.title_element == null) {\n      return html`${content}`\n    }\n\n    return html`\n      <div\n        class=\"\n        panel\n        panel-size-${this.panel.size || \"medium\"}\n        panel-level-${this.panel.level || \"info\"}\n        \"\n      >\n        <details .open=${this.panel.expanded ?? false}>\n          <summary>\n            <div class=\"panel-header\">\n              ${icon\n                ? html`\n                    <img\n                      class=\"panel-icon panel-icon-${this.panel.title_element?.icon_size}\"\n                      .src=${icon}\n                      .alt=${title}\n                    />\n                    <div>${title}</div>\n                  `\n                : html`<div>${title}</div>`}\n            </div>\n            <span class=\"arrow\">▶</span>\n          </summary>\n          <div class=\"panel-content\">\n            ${subtitle ? html`<div class=\"panel-subtitle\">${subtitle}</div>` : \"\"} ${content}\n          </div>\n        </details>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"panel-renderer\": PanelRenderer\n  }\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type { KnowledgePanelElement, KnowledgePanelsData } from \"../../../types/knowledge-panel\"\nimport \"../../../utils/knowledge-panels/heading-utils\" // Import heading renderer component\n\n/**\n * Panel element renderer component\n *\n * @element panel-element-renderer\n */\n@customElement(\"panel-element-renderer\")\nexport class PanelElementRenderer extends LitElement {\n  static override styles = css`\n    :host {\n      display: block;\n      width: 100%;\n      overflow-x: hidden; /* Prevent horizontal overflow at component level */\n    }\n\n    .warning {\n      padding: 0.75rem;\n      margin-bottom: 1rem;\n      border: 1px solid transparent;\n      border-radius: 0.25rem;\n      color: #856404;\n      background-color: #fff3cd;\n      border-color: #ffeeba;\n    }\n\n    .sub-panel {\n      box-sizing: border-box; /* Include padding in width calculation */\n      width: 100%;\n      margin-bottom: 1.25rem;\n      padding: 1rem;\n      border-left: 3px solid #e8e8e8;\n      background-color: #fafafa;\n      border-radius: 20px;\n      text-align: left;\n      box-shadow: 0 1px 4px rgba(0, 0, 0, 0.02);\n      overflow-x: hidden; /* Prevent horizontal overflow */\n      word-wrap: break-word; /* Ensure long words don't cause overflow */\n      overflow-wrap: break-word; /* Modern version of word-wrap */\n    }\n\n    .sub-panel-title {\n      width: 100%;\n      margin-top: 0;\n      margin-bottom: 0.65rem;\n      font-size: 1.05rem;\n      border-bottom: none;\n      padding-bottom: 0;\n      text-align: left;\n      word-wrap: break-word;\n    }\n\n    .elements {\n      width: 100%;\n      overflow-x: hidden; /* Prevent horizontal overflow in nested elements */\n    }\n  `\n\n  @property({ type: Object })\n  element?: KnowledgePanelElement\n\n  @property({ type: Object })\n  knowledgePanels: KnowledgePanelsData | null = null\n\n  @property({ type: String })\n  headingLevel = \"h3\"\n\n  override render(): TemplateResult {\n    if (!this.element) {\n      return html``\n    }\n\n    // For panel elements, we either render the referenced panel or its own content\n    if (this.element.panel_element?.panel_id) {\n      const panelId = this.element.panel_element.panel_id\n      // We need to get the actual panel from the panels data\n      const referencedPanel = this.knowledgePanels?.[panelId]\n      if (referencedPanel) {\n        return html`<panel-renderer\n          .panel=${referencedPanel}\n          .knowledgePanels=${this.knowledgePanels}\n          headingLevel=${this.headingLevel}\n        >\n        </panel-renderer>`\n      } else {\n        return html`<div class=\"warning\">Referenced panel not found: ${panelId}</div>`\n      }\n    } else if (this.element.elements && Array.isArray(this.element.elements)) {\n      return html`\n        <div class=\"sub-panel\">\n          ${this.element.title\n            ? html`<heading-renderer\n                text=\"${this.element.title}\"\n                class-name=\"sub-panel-title\"\n                heading-level=\"${this.headingLevel}\"\n                offset=\"1\"\n              >\n              </heading-renderer>`\n            : \"\"}\n          <div class=\"elements\">\n            ${this.element.elements.map(\n              (subElement: KnowledgePanelElement) =>\n                html`<element-renderer\n                  .element=${subElement}\n                  .knowledgePanels=${this.knowledgePanels}\n                  headingLevel=${this.headingLevel}\n                >\n                </element-renderer>`\n            )}\n          </div>\n        </div>\n      `\n    }\n    return html`<div class=\"warning\">Panel without elements</div>`\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"panel-element-renderer\": PanelElementRenderer\n  }\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type { KnowledgePanelElement, KnowledgePanelsData } from \"../../../types/knowledge-panel\"\nimport \"../../../utils/knowledge-panels/heading-utils\"\n\n/**\n * Panel group element renderer component\n *\n * @element panel-group-element-renderer\n */\n@customElement(\"panel-group-element-renderer\")\nexport class PanelGroupElementRenderer extends LitElement {\n  static override styles = css`\n    .panel-group {\n      width: 100%;\n      margin-bottom: 1.75rem;\n      text-align: left;\n    }\n\n    .panel-group-title {\n      width: 100%;\n      margin-top: 0;\n      margin-bottom: 1rem;\n      font-size: 1.15rem;\n      font-weight: 600;\n      padding-bottom: 0.5rem;\n      border-bottom: 1px solid #f0f0f0;\n      text-align: left;\n      word-wrap: break-word;\n    }\n\n    .warning {\n      padding: 0.75rem;\n      margin-bottom: 1rem;\n      border: 1px solid transparent;\n      border-radius: 0.25rem;\n      color: #856404;\n      background-color: #fff3cd;\n      border-color: #ffeeba;\n    }\n  `\n\n  @property({ type: Object })\n  element?: KnowledgePanelElement\n\n  @property({ type: Object })\n  knowledgePanels: KnowledgePanelsData | null = null\n\n  @property({ type: String })\n  headingLevel = \"h3\"\n\n  override render(): TemplateResult {\n    if (!this.element) {\n      return html``\n    }\n\n    const panelGroup = this.element.panel_group_element\n    if (!panelGroup) {\n      return html`<div class=\"warning\">\n        <heading-renderer\n          text=\"Missing Data\"\n          class-name=\"warning-title\"\n          heading-level=\"${this.headingLevel}\"\n          offset=\"1\"\n        >\n        </heading-renderer>\n        <p>Panel group without data</p>\n      </div>`\n    }\n\n    return html`\n      <div class=\"panel-group\">\n        ${panelGroup.title\n          ? html`<heading-renderer\n              text=\"${panelGroup.title}\"\n              class-name=\"panel-group-title\"\n              heading-level=\"${this.headingLevel}\"\n              offset=\"1\"\n            >\n            </heading-renderer>`\n          : \"\"}\n        <panel-group-image-renderer .panelGroup=${panelGroup}></panel-group-image-renderer>\n        ${this.renderPanelGroupPanels(panelGroup)}\n      </div>\n    `\n  }\n\n  /**\n   * Renders the panels referenced by a panel group\n   * @param panelGroup - The panel group containing panel references\n   * @returns Array of rendered panels\n   */\n  renderPanelGroupPanels(panelGroup: any): TemplateResult[] {\n    return (panelGroup.panel_ids || []).map((panelId: string) => {\n      const panel = this.knowledgePanels?.[panelId]\n      if (panel) {\n        return html`<panel-renderer\n          .panel=${panel}\n          .knowledgePanels=${this.knowledgePanels}\n          headingLevel=${this.headingLevel}\n        >\n        </panel-renderer>`\n      } else {\n        return html`<div class=\"warning\">Referenced panel not found: ${panelId}</div>`\n      }\n    })\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"panel-group-element-renderer\": PanelGroupElementRenderer\n  }\n}\n","import { LitElement, html, type TemplateResult } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type { KnowledgePanelElement, KnowledgePanelsData } from \"../../../types/knowledge-panel\"\n\nimport \"../renderers/render-text\"\nimport \"../renderers/render-table\"\nimport \"../renderers/render-titled-text\"\nimport \"../renderers/render-panel\"\nimport \"../renderers/render-panel-element\"\nimport \"../renderers/render-action\"\nimport \"../renderers/render-panel-group\"\n\n/**\n * Element renderer dispatcher component\n *\n * @element element-renderer\n */\n@customElement(\"element-renderer\")\nexport class ElementRenderer extends LitElement {\n  @property({ type: Object })\n  element?: KnowledgePanelElement\n\n  @property({ type: Object })\n  knowledgePanels: KnowledgePanelsData | null = null\n\n  @property({ type: String })\n  headingLevel = \"h3\"\n\n  override render(): TemplateResult {\n    if (!this.element || !this.element.element_type) {\n      console.error(\"Invalid element:\", this.element)\n      return html``\n    }\n\n    switch (this.element.element_type) {\n      case \"text\":\n        return html`<text-element-renderer .element=${this.element}></text-element-renderer>`\n\n      case \"table\":\n        return html`<table-element-renderer\n          .element=${this.element}\n          headingLevel=${this.headingLevel}\n        >\n        </table-element-renderer>`\n\n      case \"titled_text\":\n        return html`<titled-text-element-renderer .element=${this.element}>\n        </titled-text-element-renderer>`\n\n      case \"panel\":\n        return html`<panel-element-renderer\n          .element=${this.element}\n          .knowledgePanels=${this.knowledgePanels}\n          headingLevel=${this.headingLevel}\n        >\n        </panel-element-renderer>`\n\n      case \"panel_group\":\n        return html`<panel-group-element-renderer\n          .element=${this.element}\n          .knowledgePanels=${this.knowledgePanels}\n          headingLevel=${this.headingLevel}\n        >\n        </panel-group-element-renderer>`\n\n      case \"action\":\n        return html`<action-element-renderer .element=${this.element}> </action-element-renderer>`\n\n      default:\n        console.log(`Unsupported element type: ${this.element.element_type}`, this.element)\n        return html``\n    }\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"element-renderer\": ElementRenderer\n  }\n}\n","import { LitElement, html, css, type TemplateResult } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { fetchKnowledgePanels } from \"../../api/knowledgepanel\"\nimport { Task } from \"@lit/task\"\nimport \"../../components/shared/loader\" // Import the loader component\nimport { BASE } from \"../../styles/base\"\nimport { ALERT } from \"../../styles/alert\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\n\nimport type { KnowledgePanel, KnowledgePanelsData } from \"../../types/knowledge-panel\"\n\n// Import all renderer components\nimport \"./renderers\"\nimport \"../../utils/knowledge-panels/heading-utils\" // Import heading renderer component\nimport { extractImages } from \"../../utils/knowledge-panels/extract-images\"\n\n/**\n * `knowledge-panels` - A web component to display knowledge panels from any source\n *\n * @element knowledge-panels\n *\n * @property {string} url - The URL to fetch the knowledge panels from\n * @property {string} path - The path to the knowledge panels inside the JSON response (e.g., \"product.knowledge_panels\")\n * @property {string} headingLevel - The heading level to use for panel titles (h2, h3, h4, h5, h6)\n */\n@customElement(\"knowledge-panels\")\nexport class KnowledgePanelsComponent extends LitElement {\n  static override styles = [\n    BASE,\n    ALERT,\n    ...getButtonClasses([ButtonType.Chocolate, ButtonType.Cappucino]),\n    css`\n      :host {\n        display: block;\n        width: 100%;\n        max-width: 100%;\n        margin-bottom: 1.5rem;\n        box-sizing: border-box;\n        overflow-x: hidden; /* Prevent horizontal scrolling */\n        padding: 0 0.5rem;\n      }\n\n      /* Apply box-sizing to all elements */\n      *,\n      *:before,\n      *:after {\n        box-sizing: border-box;\n      }\n\n      /* Knowledge panels container */\n      .knowledge-panels-container {\n        width: 100%;\n        text-align: left;\n        overflow-x: hidden; /* Prevent horizontal scrolling */\n      }\n      .info {\n        padding: 0.75rem;\n        margin-bottom: 1rem;\n        border: 1px solid transparent;\n        border-radius: 0.25rem;\n        color: #0c5460;\n        background-color: #d1ecf1;\n        border-color: #bee5eb;\n      }\n\n      .loading {\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        padding: 2rem;\n      }\n    `,\n  ]\n\n  @property({\n    type: String,\n    reflect: true,\n    attribute: \"heading-level\", // Explicitly match the attribute name\n  })\n  headingLevel = \"h3\" // Set a default value\n\n  /** Array of top panel keys to render */\n  @property({ type: Array, attribute: \"top-panels\" })\n  panels: string[] = [\"root\"]\n\n  /** If true, the top panels will be rendered within a frame */\n  @property({ type: Boolean, attribute: \"top-frame\" })\n  topFrame = false\n\n  @property({ type: String })\n  url = \"\"\n\n  @property({ type: String })\n  path = \"\"\n\n  @state()\n  private knowledgePanels: KnowledgePanelsData | null = null\n\n  @state()\n  private nutritionImages: string[] = []\n\n  /**\n   * Task to fetch knowledge panels\n   */\n  private _knowledgePanelsTask = new Task(this, {\n    task: async ([url, path]: [string, string]) => {\n      if (!url || !path) {\n        return null\n      }\n      return await fetchKnowledgePanels(url, path)\n    },\n    args: () => [this.url, this.path] as [string, string],\n  })\n\n  /**\n   * Handle errors in a more user-friendly way\n   * @param error - The error to display\n   * @returns Template result for the error display\n   */\n  renderError(error: unknown): TemplateResult {\n    console.error(\"Task error:\", error)\n    const errorMessage = error instanceof Error ? error.message : String(error)\n\n    return html`\n      <slot name=\"error\">\n        <heading-renderer\n          text=\"Error Loading Knowledge Panels\"\n          class-name=\"error-title\"\n          heading-level=\"${this.headingLevel}\"\n        >\n        </heading-renderer>\n        <p>${errorMessage}</p>\n        <button class=\"button cappucino-button\" @click=${this._retryLoad}>Retry</button>\n      </slot>\n    `\n  }\n\n  /**\n   * Handle retry of data loading\n   * @private\n   */\n  private _retryLoad(): void {\n    this._knowledgePanelsTask.run()\n  }\n\n  /**\n   * Main render method for the component\n   * @returns Template result for the entire component\n   */\n  override render(): TemplateResult {\n    return this._knowledgePanelsTask.render({\n      initial: () => html`<div class=\"info\">Ready to load knowledge panels.</div>`,\n      pending: () => html`<off-wc-loader></off-wc-loader>`,\n      complete: (result) => this.renderPanelsResult(result),\n      error: (error: unknown) => this.renderError(error),\n    })\n  }\n\n  /**\n   * Renders the panels data once it has been loaded\n   * @param result - The panels data from the API\n   * @returns Template result for the panels\n   */\n  renderPanelsResult(result: unknown): TemplateResult {\n    const panels = result as KnowledgePanelsData\n    console.log(\"Panels received:\", panels)\n\n    if (!panels || typeof panels !== \"object\") {\n      console.error(\"Invalid panels data:\", panels)\n      return html`<slot name=\"error\">Invalid data format received</slot>`\n    }\n\n    if (Object.keys(panels).length === 0) {\n      // Use a heading for the empty state message\n      const emptyHeading = \"No Knowledge Panels Available\"\n      return html`\n        <div class=\"info\">\n          <heading-renderer\n            text=\"${emptyHeading}\"\n            class-name=\"empty-heading\"\n            heading-level=\"${this.headingLevel}\"\n          >\n          </heading-renderer>\n          <p>No knowledge panels were found for this request.</p>\n        </div>\n      `\n    }\n\n    // Store panels in the instance for reference\n    this.knowledgePanels = panels\n\n    // Extract all nutrition-related images\n    this.nutritionImages = extractImages(panels)\n\n    const panelsToRender = Object.entries(panels)\n      .filter(([key]) => this.panels.includes(key))\n      .map(([, panel]) => panel)\n\n    return html`\n      <div class=\"knowledge-panels-container\">\n        ${panelsToRender.map((panel: KnowledgePanel) =>\n          panel\n            ? html`<panel-renderer\n                .panel=${panel}\n                .knowledgePanels=${this.knowledgePanels}\n                .nutritionImages=${this.nutritionImages}\n                .frame=${this.topFrame}\n                .headingLevel=${this.headingLevel}\n              >\n              </panel-renderer>`\n            : html``\n        )}\n      </div>\n    `\n  }\n\n  /**\n   * Updated callback - called when element attributes change\n   * @param changedProperties - Map of changed properties\n   */\n  override updated(changedProperties: Map<string, unknown>): void {\n    super.updated(changedProperties)\n\n    if (changedProperties.has(\"url\") || changedProperties.has(\"path\")) {\n      // Reset state when URL or path changes\n      this.knowledgePanels = null\n      this.nutritionImages = []\n    }\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"knowledge-panels\": KnowledgePanelsComponent\n  }\n}\n","// src/utils/dark-mode-listener.ts\n// Simple singleton for dark mode detection and subscription\n\nexport type DarkModeCallback = (isDark: boolean) => void\n\nclass DarkModeListener {\n  private isDark: boolean\n  private listeners: Set<DarkModeCallback> = new Set()\n  private mq: MediaQueryList\n\n  constructor() {\n    this.mq = window.matchMedia(\"(prefers-color-scheme: dark)\")\n    this.isDark = this.mq.matches\n    this.mq.addEventListener(\"change\", this.handleChange)\n  }\n\n  private handleChange = (e: MediaQueryListEvent) => {\n    this.isDark = e.matches\n    this.listeners.forEach((cb) => cb(this.isDark))\n  }\n\n  get darkMode() {\n    return this.isDark\n  }\n\n  subscribe(cb: DarkModeCallback) {\n    this.listeners.add(cb)\n    // Immediately call with current value\n    cb(this.isDark)\n  }\n\n  unsubscribe(cb: DarkModeCallback) {\n    this.listeners.delete(cb)\n  }\n}\n\nexport const darkModeListener = new DarkModeListener()\n","import { LitElement, html, css } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { localized, msg, str } from \"@lit/localize\"\nimport { getImageUrl, languageCode } from \"../../signals/app\"\nimport { classMap } from \"lit/directives/class-map.js\"\nimport { darkModeListener } from \"../../utils/dark-mode-listener\"\n\n/**\n * Donation banner\n * @element donation-banner\n * It requires one of the following fonts for each list item to be loaded:\n * - \"Gill Sans\", \"Gill Sans MT\", Calibri, \"Trebuchet MS\", sans-serif\n * - \"Public Sans\", Helvetica, Roboto, Arial, sans-serif\n * - \"Segoe UI\", Tahoma, Geneva, Verdana, sans-serif\n */\n@customElement(\"donation-banner\")\n@localized()\nexport class DonationBanner extends LitElement {\n  /**\n   * The links to the donation page\n   * @type {Object}\n   */\n  @property({ type: Object })\n  links = {\n    fr: \"https://open-food-facts.assoconnect.com/collect/description/476750-c-faire-un-don-a-open-food-facts\",\n    default: \"https://world.openfoodfacts.org/donate-to-open-food-facts\",\n  }\n\n  /**\n   * The fundraiser year (next year)\n   * @type {String}\n   */\n  @property({ type: String, reflect: true })\n  currentYear: string = this.getDefaultYear()\n\n  /**\n   * Whether to apply dark mode styling (auto-detected from prefers-color-scheme)\n   */\n  isDarkMode = darkModeListener.darkMode\n  private _darkModeCb = (isDark: boolean) => {\n    this.isDarkMode = isDark\n    this.requestUpdate()\n  }\n\n  override connectedCallback() {\n    super.connectedCallback()\n    darkModeListener.subscribe(this._darkModeCb)\n  }\n\n  override disconnectedCallback() {\n    darkModeListener.unsubscribe(this._darkModeCb)\n    super.disconnectedCallback()\n  }\n\n  getDefaultYear() {\n    return (new Date().getFullYear() + 1).toString()\n  }\n\n  getLinkWithQueryParams(link: string) {\n    const url = new URL(link)\n    const params = new URLSearchParams(url.search)\n    if (!params.has(\"utm_source\")) params.set(\"utm_source\", \"off\")\n    if (!params.has(\"utm_medium\")) params.set(\"utm_medium\", \"web\")\n    if (!params.has(\"utm_campaign\")) params.set(\"utm_campaign\", `donate-${this.currentYear}-a`)\n    if (!params.has(\"utm_term\")) params.set(\"utm_term\", \"en-text-button\")\n    url.search = params.toString()\n    return url.toString()\n  }\n\n  get donateLink() {\n    const locale = languageCode.get()\n    const link =\n      locale in this.links ? this.links[locale as keyof typeof this.links] : this.links.default\n    return this.getLinkWithQueryParams(link)\n  }\n\n  static override styles = css`\n    .donation-banner,\n    .donation-banner-footer {\n      position: relative;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      padding: 20px 0;\n      border: 10px solid #ff6e78;\n      width: 100%;\n      background-color: white;\n      box-sizing: border-box;\n      border-radius: 20px;\n    }\n    .dark-mode .donation-banner,\n    .dark-mode .donation-banner-footer {\n      background-color: #2d2724;\n      color: #f9f7f5;\n      border-color: #ff6e78;\n      border-radius: 20px;\n    }\n    .dark-mode .donation-banner__main-title,\n    .dark-mode .donation-banner-footer__main-title {\n      color: #ff6e78;\n    }\n    .dark-mode .donation-banner__main-div-wrapper {\n      color: #f9f7f5;\n    }\n    .dark-mode .donation-banner__hook-section,\n    .dark-mode .donation-banner-footer__hook-section {\n      background-color: #0050a0;\n      color: #fff;\n    }\n    @media (max-width: 732px) {\n      .donation-banner,\n      .donation-banner-footer {\n        flex-direction: column;\n        padding: 20px 10px;\n      }\n    }\n    .group-image {\n      height: auto;\n      max-width: 100%;\n      display: inline-block;\n      vertical-align: middle;\n    }\n    .donation-banner__group-photo,\n    .donation-banner-footer__group-photo {\n      border-radius: 5px;\n    }\n    .donation-banner__close button,\n    .donation-banner-footer__close button {\n      position: absolute;\n      top: 0.3rem;\n      right: 0.3rem;\n      cursor: pointer;\n      background-color: transparent;\n      color: inherit;\n    }\n    .donation-banner__hook-section,\n    .donation-banner-footer__hook-section {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      background-color: #008c8c;\n      color: white;\n      padding: 10px;\n      margin: 10px;\n      border-radius: 10px;\n      z-index: 1;\n    }\n    .donation-banner__hook-section p,\n    .donation-banner-footer__hook-section p {\n      font-family: \"Gill Sans\", \"Gill Sans MT\", Calibri, \"Trebuchet MS\", sans-serif;\n      font-size: 25px;\n      font-weight: 700;\n      line-height: 35px;\n      text-transform: uppercase;\n      margin: 0;\n    }\n    @media (max-width: 732px) {\n      .donation-banner__hook-section p,\n      .donation-banner-footer__hook-section p {\n        font-size: 15px;\n        line-height: 20px;\n      }\n    }\n    .donation-banner__left-aside,\n    .donation-banner-footer__left-aside {\n      width: 60%;\n      margin: 0 10px;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n    .donation-banner__left-aside img,\n    .donation-banner-footer__left-aside img {\n      transform: translatey(-15px);\n    }\n    .donation-banner__aside,\n    .donation-banner-footer__aside {\n      display: flex;\n      flex-direction: column;\n    }\n    .donation-banner__main-title,\n    .donation-banner-footer__main-title {\n      font-family: \"Public Sans\", Helvetica, Roboto, Arial, sans-serif;\n      color: #ff6e78;\n      font-weight: 800;\n      font-size: 25px;\n      margin: 0.2rem 0rem 0.5rem;\n      font-weight: 500;\n    }\n    .donation-banner__main-div-wrapper {\n      color: black;\n    }\n    .donation-banner__main-div {\n      font-family: \"Public Sans\", Helvetica, Roboto, Arial, sans-serif;\n    }\n    .donation-banner__main-section,\n    .donation-banner-footer__main-section {\n      display: flex;\n      align-items: center;\n    }\n    .donation-banner__actions-section,\n    .donation-banner-footer__actions-section {\n      display: flex;\n      justify-content: space-around;\n      gap: 15px;\n      padding: 0 10px;\n    }\n    @media (max-width: 732px) {\n      .donation-banner__actions-section,\n      .donation-banner-footer__actions-section {\n        flex-direction: column;\n        align-items: center;\n        padding: 20px 10px;\n      }\n    }\n    .donation-banner__actions-section__financial,\n    .donation-banner-footer__actions-section__financial {\n      width: 50%;\n    }\n    @media (max-width: 732px) {\n      .donation-banner__actions-section__financial,\n      .donation-banner-footer__actions-section__financial {\n        width: 90%;\n      }\n    }\n    .donation-banner__actions-section__financial p,\n    .donation-banner-footer__actions-section__financial p {\n      font-family: \"Gill Sans\", \"Gill Sans MT\", Calibri, \"Trebuchet MS\", sans-serif;\n      font-size: 15px;\n      color: #008c8c;\n      font-weight: bolder;\n    }\n    .donation-banner__actions-section__donate-button,\n    .donation-banner-footer__actions-section__donate-button {\n      width: 40%;\n    }\n    .donation-banner__actions-section__donate-button a button,\n    .donation-banner-footer__actions-section__donate-button a button {\n      background-color: #ff6e78;\n      border-radius: 30px;\n      font-family: \"Segoe UI\", Tahoma, Geneva, Verdana, sans-serif;\n      font-size: 20px;\n      font-weight: 900;\n      padding: 1.1428571429rem 2.2857142857rem 1.2142857143rem;\n      color: white;\n      border: none;\n      cursor: pointer;\n    }\n    @media (max-width: 837px) {\n      .donation-banner-footer__actions-section__donate-button a button {\n        padding: 1rem 2rem 1rem;\n        font-size: 16px;\n      }\n    }\n    @media (min-width: 733px) and (max-width: 837px) {\n      .donation-banner-footer__actions-section__donate-button a button {\n        padding: 1rem 2rem 1rem;\n        font-size: 16px;\n        margin-left: -15px;\n      }\n    }\n    .donation-banner__actions-section__donate-button a button:hover,\n    .donation-banner-footer__actions-section__donate-button a button:hover {\n      background-color: rgba(255, 110, 120, 0.8);\n    }\n    .unordered-list {\n      margin-left: 15.4px;\n      margin-bottom: 20px;\n      margin-top: 0;\n      padding: 1px;\n      line-height: 1.6;\n      font-size: 14px;\n      padding-right: 10px;\n    }\n    .unordered-list li p {\n      margin: 0;\n    }\n  `\n\n  override render() {\n    const rootClasses = { \"dark-mode\": this.isDarkMode }\n    return html`<section class=${classMap(rootClasses)}>\n      <div class=\"donation-banner-footer row\">\n        <div class=\"donation-banner-footer__left-aside\">\n          <div class=\"donation-banner-footer__hook-section\">\n            <p>\n              ${msg(\"Help us inform millions of consumers around the world about what they eat\")}\n            </p>\n          </div>\n          <img\n            class=\"group-image\"\n            src=\"${getImageUrl(\"donation-banner-group-photo.png\")}\"\n            alt=\"${msg(str`group photo donation ${this.currentYear}`)}\"\n          />\n        </div>\n        <div class=\"donation-banner__main-div-wrapper\">\n          <div style=\"padding-left: 16px;\">\n            <div class=\"donation-banner-footer__main-section\">\n              <img\n                width=\"50\"\n                height=\"50\"\n                src=\"${getImageUrl(\"CMJN-ICON_WHITE_BG_OFF.svg\")}\"\n                alt=\"open food facts logo\"\n              />\n              <h3 class=\"donation-banner-footer__main-title\">\n                ${msg(str`Please give to our ${this.currentYear} Fundraiser`)}\n              </h3>\n            </div>\n            <p style=\"margin: 0 0 20px; font-size: 14px;\">\n              ${msg(\"Your donations fund the day-to-day operations of our non-profit association:\")}\n            </p>\n            <ul class=\"unordered-list\">\n              <li>${msg(\"keeping our database open & available to all,\")}</li>\n              <li>\n                ${msg(\"technical infrastructure (website/mobile app) & a small permanent team\")}\n              </li>\n              <li>\n                <p>${msg(\"remain independent of the food industry,\")}</p>\n              </li>\n              <li>\n                <p>${msg(\"engage a community of committed citizens,\")}</p>\n              </li>\n              <li>\n                <p>${msg(\"support the advancement of public health research.\")}</p>\n              </li>\n            </ul>\n          </div>\n          <div class=\"donation-banner-footer__actions-section\">\n            <div class=\"donation-banner-footer__actions-section__financial\">\n              <p style=\"margin: 0px; line-height: 1.6\">\n                ${msg(\n                  \"Each donation counts! We appreciate your support in bringing further food transparency in the world.\"\n                )}\n              </p>\n            </div>\n            <div class=\"donation-banner-footer__actions-section__donate-button\">\n              <a href=\"${this.donateLink}\">\n                <button>${msg(\"I SUPPORT\")}</button>\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n    </section>`\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"donation-banner\": DonationBanner\n  }\n}\n","import { LitElement, html, css, nothing } from \"lit\"\nimport { customElement, state, property } from \"lit/decorators.js\"\nimport { localized, msg } from \"@lit/localize\"\nimport { getImageUrl, languageCode } from \"../../signals/app\"\nimport { classMap } from \"lit/directives/class-map.js\"\nimport { darkModeListener } from \"../../utils/dark-mode-listener\"\n\nexport type Badge = {\n  href: string\n  src: string\n  alt: string\n  id: string\n  hide: boolean\n  errorHandler?: (event: Event) => void\n}\n\n/**\n * Mobile Badges\n * @element mobile-badges\n * A web component that displays mobile app badges for downloading the Open Food Facts app.\n * It includes badges for Google Play, F-Droid, APK, and the Apple App Store.\n */\n@customElement(\"mobile-badges\")\n@localized()\nexport class MobileBadges extends LitElement {\n  /**\n   * Styles for the component.\n   */\n  static override styles = [\n    css`\n      :host {\n        display: block;\n      }\n      .dark-mode {\n        background-color: #201a17;\n        color: #f9f7f5;\n      }\n      #footer_scan {\n        color: #000;\n      }\n      .dark-mode #footer_scan {\n        color: #f9f7f5;\n      }\n      .everyday {\n        background-color: #0064c8;\n        border-inline: 5px solid #0064c8;\n        color: #fff;\n      }\n      .dark-mode .everyday {\n        background-color: #0050a0;\n        border-inline: 5px solid #0050a0;\n        color: #fff;\n      }\n      .foods {\n        background-color: #ff8714;\n        border-inline: 5px solid #ff8714;\n        color: #fff;\n      }\n      .dark-mode .foods {\n        background-color: #cc6c10;\n        border-inline: 5px solid #cc6c10;\n        color: #fff;\n      }\n      #install_the_app_block {\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        flex-wrap: wrap;\n        gap: 2rem;\n      }\n      #footer_install_the_app {\n        font-family: \"Public Sans\", Helvetica, Roboto, Arial, sans-serif;\n        font-weight: 550;\n        font-size: 26px;\n        line-height: 30px;\n        text-transform: uppercase;\n        margin-bottom: 8px;\n      }\n      #footer_scan {\n        font-family: \"Public Sans\", Helvetica, Roboto, Arial, sans-serif;\n        font-style: normal;\n        font-weight: 550;\n        font-size: 22px;\n        line-height: 28px;\n        display: flex;\n        align-items: center;\n        text-align: center;\n        color: #000;\n        max-width: 420px;\n      }\n      @media (max-width: 480px) {\n        #footer_install_the_app {\n          font-size: 20px;\n          line-height: 24px;\n        }\n        #footer_scan {\n          font-size: 18px;\n          line-height: 22px;\n        }\n      }\n      @media (min-width: 768px) {\n        #footer_install_the_app {\n          font-size: 28px;\n          line-height: 32px;\n        }\n        #footer_scan {\n          font-size: 24px;\n          line-height: 30px;\n        }\n      }\n      @media (min-width: 1024px) {\n        #footer_install_the_app {\n          font-size: 30px;\n          line-height: 34px;\n        }\n        #footer_scan {\n          font-size: 26px;\n          line-height: 32px;\n        }\n      }\n      .everyday {\n        transform: rotate(2.5deg);\n        background-color: #0064c8;\n        border-inline: 5px solid #0064c8;\n        line-height: 130%;\n        font-weight: 550;\n        color: #fff;\n        border-radius: 5px;\n        text-transform: uppercase;\n        display: inline-block;\n      }\n      .foods {\n        transform: rotate(-3deg);\n        background-color: #ff8714;\n        border-inline: 5px solid #ff8714;\n        line-height: 130%;\n        font-weight: 550;\n        color: #fff;\n        border-radius: 5px;\n        text-transform: uppercase;\n        display: inline-block;\n      }\n      .no-text-decoration {\n        text-decoration: none;\n      }\n      .badge-container {\n        display: grid;\n        gap: 0.2rem; /* Reduced horizontal gap */\n        grid-template-columns: repeat(2, 1fr);\n      }\n      @media (min-width: 768px) {\n        .badge-container {\n          grid-template-columns: repeat(4, 1fr);\n        }\n      }\n      .responsive-container {\n        flex-direction: column;\n        text-align: center;\n      }\n      @media (min-width: 768px) {\n        .badge-container {\n          display: flex;\n          justify-content: center;\n        }\n      }\n      @media (max-width: 480px) {\n        .badge-container {\n          grid-template-columns: 1fr;\n          gap: 0.5rem;\n        }\n        .responsive-container {\n          flex-direction: column;\n          text-align: center;\n        }\n        .responsive-image {\n          margin-bottom: 1rem;\n        }\n        .responsive-text {\n          margin-top: 0.5rem;\n        }\n      }\n      #fdroid_badge {\n        transform: scale(1.1);\n        height: 50px;\n        margin-top: -4px;\n      }\n      #playstore_badge {\n        height: 45px;\n      }\n\n      .logo-container {\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        max-width: 720px;\n        gap: 2rem;\n        flex-wrap: wrap;\n      }\n    `,\n  ]\n\n  /**\n   * Controls visibility of Google Play Store badge\n   */\n  @property({ type: Boolean, attribute: \"hide-play-store\" })\n  hidePlayStore: boolean = false\n\n  /**\n   * Controls visibility of F-Droid badge\n   */\n  @property({ type: Boolean, attribute: \"hide-f-droid\" })\n  hideFDroid: boolean = false\n\n  /**\n   * Controls visibility of APK download badge\n   */\n  @property({ type: Boolean, attribute: \"hide-apk\" })\n  hideApk: boolean = false\n\n  /**\n   * Controls visibility of App Store badge\n   */\n  @property({ type: Boolean, attribute: \"hide-app-store\" })\n  hideAppStore: boolean = false\n\n  /**\n   * Controls visibility of App Store badge\n   */\n  @property({ type: Boolean, attribute: \"hide-image\" })\n  hideImage: boolean = false\n\n  /**\n   * Whether to apply dark mode styling (auto-detected from prefers-color-scheme)\n   */\n  isDarkMode = darkModeListener.darkMode\n  private _darkModeCb = (isDark: boolean) => {\n    this.isDarkMode = isDark\n    this.requestUpdate()\n  }\n\n  override connectedCallback() {\n    super.connectedCallback()\n    darkModeListener.subscribe(this._darkModeCb)\n  }\n\n  override disconnectedCallback() {\n    darkModeListener.unsubscribe(this._darkModeCb)\n    super.disconnectedCallback()\n  }\n\n  /**\n   * Link to the F-Droid app page.\n   */\n  @state()\n  fDroidAppLink = \"https://f-droid.org/packages/openfoodfacts.github.scrachx.openfood\"\n\n  /**\n   * Generates the URL suffix for Android app links.\n   * @param language - The language code.\n   * @param campaign - The campaign identifier.\n   * @returns The URL suffix with UTM parameters.\n   */\n  private getAndroidUrlSuffix(language: string, campaign: string): string {\n    return `?utm_source=off&utf_medium=web&utm_campaign=${campaign}_${language}`\n  }\n\n  /**\n   * Generates the Google Play Store link for the app.\n   * @param language - The language code.\n   * @returns The Google Play Store link.\n   */\n  getAndroidAppLink(language: string): string {\n    const baseURI = `https://play.google.com/store/apps/details?id=org.openfoodfacts.scanner&hl=${language}`\n    return `${baseURI}${this.getAndroidUrlSuffix(language, \"install_the_app_android_footer\")}`\n  }\n\n  /**\n   * Generates the APK download link for the app.\n   * @param language - The language code.\n   * @returns The APK download link.\n   */\n  getAndroidApkAppLink(language: string): string {\n    const baseURI = \"https://github.com/openfoodfacts/smooth-app/releases/latest\"\n    return `${baseURI}${this.getAndroidUrlSuffix(language, \"install_the_app_apk_footer\")}`\n  }\n\n  /**\n   * Generates the path to the Google Play Store badge icon.\n   * @param language - The language code.\n   * @returns The path to the badge icon.\n   */\n  getAndroidAppIconPath(language: string): string {\n    return `https://play.google.com/intl/en_us/badges/static/images/badges/${language}_badge_web_generic.png`\n  }\n\n  /**\n   * Generates the path to the F-Droid badge icon.\n   * @param language - The language code.\n   * @returns The path to the badge icon.\n   */\n  getFDroidAppIconPath(language: string): string {\n    return `https://fdroid.gitlab.io/artwork/badge/get-it-on-${language}.png`\n  }\n\n  /**\n   * Generates the path to the Apple App Store badge icon.\n   * Note: This code does not handle the US locale specifically.\n   * @param language - The language code.\n   * @returns The path to the badge icon.\n   */\n  getIosAppIconPath(language: string): string {\n    if (language === \"en\") {\n      return \"appstore/black/appstore_UK.svg\"\n    }\n    return `appstore/black/appstore_${language.toLocaleUpperCase()}.svg`\n  }\n\n  /**\n   * Generates the Apple App Store link for the app.\n   * @param language - The language code.\n   * @returns The Apple App Store link.\n   */\n  getIosAppLink(language: string): string {\n    const baseURI =\n      \"https://apps.apple.com/app/open-food-facts/id588797948?utm_source=off&utf_medium=web\"\n    return `${baseURI}&utm_campaign=install_the_app_ios_footer_${language}`\n  }\n\n  /**\n   * Generates the HTML for a badge link.\n   * @param href - The URL for the badge link.\n   * @param src - The source of the badge image.\n   * @param alt - The alt text for the badge image.\n   * @param id - The id for the badge image.\n   * @param errorHandler - The error handler for the image.\n   * @returns The HTML template for the badge link.\n   */\n  private generateBadgeLink(\n    href: string,\n    src: string,\n    alt: string,\n    id: string,\n    errorHandler?: (e: Event) => void\n  ) {\n    return html`\n      <a class=\"no-text-decoration\" href=\"${href}\">\n        <img\n          id=\"${id}\"\n          src=\"${src}\"\n          alt=\"${alt}\"\n          loading=\"lazy\"\n          height=\"40\"\n          width=\"120\"\n          @error=${errorHandler}\n        />\n      </a>\n    `\n  }\n\n  /**\n   * Filters the badges based on the hide properties.\n   * @returns The filtered list of badges.\n   **/\n  getFilteredBadges(): Badge[] {\n    const language = languageCode.get()\n    const badges: Badge[] = [\n      {\n        href: this.getAndroidAppLink(language),\n        src: this.getAndroidAppIconPath(language),\n        alt: msg(\"Get It On Google Play\"),\n        id: \"playstore_badge\",\n        hide: this.hidePlayStore,\n        errorHandler: (e: Event) => {\n          const target = e.target as HTMLImageElement\n          target.src = this.getAndroidAppIconPath(\"en\")\n        },\n      },\n      {\n        href: this.fDroidAppLink,\n        src: this.getFDroidAppIconPath(language),\n        alt: msg(\"Available on F-Droid\"),\n        id: \"fdroid_badge\",\n        hide: this.hideFDroid,\n        errorHandler: (e: Event) => {\n          const target = e.target as HTMLImageElement\n          target.src = this.getFDroidAppIconPath(\"en\")\n        },\n      },\n      {\n        href: this.getAndroidApkAppLink(language),\n        src: getImageUrl(\"download-apk_en.svg\"),\n        alt: msg(\"Android APK\"),\n        id: \"apk_badge\",\n        hide: this.hideApk,\n      },\n      {\n        href: this.getIosAppLink(language),\n        src: getImageUrl(this.getIosAppIconPath(language)),\n        alt: msg(\"Download on the App Store\"),\n        id: \"appstore_badge\",\n        hide: this.hideAppStore,\n        errorHandler: (e: Event) => {\n          const target = e.target as HTMLImageElement\n          target.src = getImageUrl(this.getIosAppIconPath(\"en\"))\n        },\n      },\n    ]\n\n    const filteredBadges = badges.filter((badge) => badge.hide == false)\n    return filteredBadges\n  }\n\n  /**\n   * Renders the image if hideImage is false\n   * @returns The image HTML or nothing if hideImage is true.\n   **/\n  renderImage() {\n    if (this.hideImage) {\n      return nothing\n    }\n    return html`\n      <div class=\"logo-container\">\n        <img\n          class=\"responsive-image\"\n          src=\"${getImageUrl(\"app-icon-in-the-clouds.svg\")}\"\n          alt=\"The Open Food Facts logo in the cloud\"\n          style=\"height:120px\"\n        />\n        <div id=\"footer_scan\" style=\"display:block\">\n          <div id=\"footer_install_the_app\">${msg(\"Install the app!\")}</div>\n          <!-- TODO find fix to add text between span for translations ex for fr : \"Scannez vos <span class=\"foods\">aliments</span> de votre <span class=\"everyday\">quotidien</span>\" -->\n          ${msg(\n            html`Scan your <span class=\"everyday\">everyday</span> <span class=\"foods\">foods</span>`\n          )}\n        </div>\n      </div>\n    `\n  }\n\n  /**\n   * Renders the badges if there are any filtered badges\n   * @returns The badges HTML or nothing if there are no filtered badges.\n   **/\n  renderBadges() {\n    const filteredBadges = this.getFilteredBadges()\n\n    return html` ${filteredBadges.length > 0\n      ? html`\n          <div class=\"badge-container \">\n            ${filteredBadges.map((badge) =>\n              this.generateBadgeLink(badge.href, badge.src, badge.alt, badge.id, badge.errorHandler)\n            )}\n          </div>\n        `\n      : \"\"}`\n  }\n\n  override render() {\n    const rootClasses = { \"dark-mode\": this.isDarkMode }\n    return html`\n      <div class=${classMap(rootClasses)} id=\"install_the_app_block\">\n        ${this.renderImage()} ${this.renderBadges()}\n      </div>\n    `\n  }\n}\n","import { LitElement, html } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport { getImageUrl } from \"../../signals/app\"\nimport { localized, msg } from \"@lit/localize\"\nimport { styleMap } from \"lit-html/directives/style-map.js\"\n\n@customElement(\"download-app-qr-code\")\n@localized()\nexport class DownloadAppQrCode extends LitElement {\n  @property({ type: Object, attribute: \"style-options\" })\n  styleOptions = {\n    width: \"180px\",\n    height: \"180px\",\n  }\n\n  override render() {\n    return html`\n      <img\n        style=${styleMap(this.styleOptions)}\n        src=${getImageUrl(\"qrcode_en.svg\")}\n        alt=${msg(\"Download the OFF app with this QR code\")}\n        title=${msg(\"Download the OFF app with this QR code\")}\n      />\n    `\n  }\n}\n","import { localized, msg } from \"@lit/localize\"\nimport { LitElement, html, css } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n\n@customElement(\"barcode-icon\")\n@localized()\nexport class BarcodeIcon extends LitElement {\n  static override styles = css`\n    :host {\n      display: inline-block;\n      width: 37px;\n      height: 37px;\n    }\n    svg {\n      width: 100%;\n      height: 100%;\n    }\n  `\n\n  override render() {\n    return html`\n      <svg\n        width=\"37\"\n        height=\"37\"\n        viewBox=\"0 0 37 37\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n      >\n        <title>${msg(\"Barcode corners icon\")}</title>\n        <g id=\"Barcode-corners\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n          <g id=\"icons8-barcode\" transform=\"translate(0, 2)\" fill=\"#FFFFFF\" fill-rule=\"nonzero\">\n            <path\n              d=\"M0.80952381,8.36507937 C1.26825397,8.36507937 1.61904762,8.01428571 1.61904762,7.55555556 L1.61904762,3.50793651 C1.61904762,2.45555556 2.45555556,1.61904762 3.50793651,1.61904762 L7.55555556,1.61904762 C8.01428571,1.61904762 8.36507937,1.26825397 8.36507937,0.80952381 C8.36507937,0.350793651 8.01428571,0 7.55555556,0 L3.50793651,0 C1.56507937,0 0,1.56507937 0,3.50793651 L0,7.55555556 C0,8.01428571 0.350793651,8.36507937 0.80952381,8.36507937 Z M3.50793651,33 L7.55555556,33 C8.01428571,33 8.36507937,32.6492063 8.36507937,32.1904762 C8.36507937,31.731746 8.01428571,31.3809524 7.55555556,31.3809524 L3.50793651,31.3809524 C2.45555556,31.3809524 1.61904762,30.5444444 1.61904762,29.4920635 L1.61904762,25.4444444 C1.61904762,24.9857143 1.26825397,24.6349206 0.80952381,24.6349206 C0.350793651,24.6349206 0,24.9857143 0,25.4444444 L0,29.4920635 C0,31.4349206 1.56507937,33 3.50793651,33 Z M36.1904762,24.6349206 C35.731746,24.6349206 35.3809524,24.9857143 35.3809524,25.4444444 L35.3809524,29.4920635 C35.3809524,30.5444444 34.5444444,31.3809524 33.4920635,31.3809524 L29.4444444,31.3809524 C28.9857143,31.3809524 28.6349206,31.731746 28.6349206,32.1904762 C28.6349206,32.6492063 28.9857143,33 29.4444444,33 L33.4920635,33 C35.4349206,33 37,31.4349206 37,29.4920635 L37,25.4444444 C37,24.9857143 36.6492063,24.6349206 36.1904762,24.6349206 Z M33.2871429,1 L29.2395238,1 C28.7807937,1 28.43,1.35079365 28.43,1.80952381 C28.43,2.26825397 28.7807937,2.61904762 29.2395238,2.61904762 L33.2871429,2.61904762 C34.3395238,2.61904762 35.1760317,3.45555556 35.1760317,4.50793651 L35.1760317,8.55555556 C35.1760317,9.01428571 35.5268254,9.36507937 35.9855556,9.36507937 C36.4442857,9.36507937 36.7950794,9.01428571 36.7950794,8.55555556 L36.7950794,4.50793651 C36.7950794,2.56507937 35.23,1 33.2871429,1 Z M10.984127,27.2857143 C11.4428571,27.2857143 11.7936508,26.8453917 11.7936508,26.2695853 L11.7936508,7.30184332 C11.7936508,6.72603687 11.4428571,6.28571429 10.984127,6.28571429 C10.5253968,6.28571429 10.1746032,6.72603687 10.1746032,7.30184332 L10.1746032,26.2695853 C10.1746032,26.8453917 10.5253968,27.2857143 10.984127,27.2857143 Z M6.98412698,27.2857143 C7.44285714,27.2857143 7.79365079,26.8453917 7.79365079,26.2695853 L7.79365079,7.30184332 C7.79365079,6.72603687 7.44285714,6.28571429 6.98412698,6.28571429 C6.52539683,6.28571429 6.17460317,6.72603687 6.17460317,7.30184332 L6.17460317,26.2695853 C6.17460317,26.8453917 6.52539683,27.2857143 6.98412698,27.2857143 Z M14.7619048,27.2857143 C15.2206349,27.2857143 15.5714286,26.8453917 15.5714286,26.2695853 L15.5714286,7.30184332 C15.5714286,6.72603687 15.2206349,6.28571429 14.7619048,6.28571429 C14.3031746,6.28571429 13.952381,6.72603687 13.952381,7.30184332 L13.952381,26.2695853 C13.952381,26.8453917 14.3031746,27.2857143 14.7619048,27.2857143 Z M18.5396825,27.2857143 C18.9984127,27.2857143 19.3492063,26.8453917 19.3492063,26.2695853 L19.3492063,7.30184332 C19.3492063,6.72603687 18.9984127,6.28571429 18.5396825,6.28571429 C18.0809524,6.28571429 17.7301587,6.72603687 17.7301587,7.30184332 L17.7301587,26.2695853 C17.7301587,26.8453917 18.0809524,27.2857143 18.5396825,27.2857143 Z M26.015873,27.2857143 C26.4746032,27.2857143 26.8253968,26.8453917 26.8253968,26.2695853 L26.8253968,7.30184332 C26.8253968,6.72603687 26.4746032,6.28571429 26.015873,6.28571429 C25.5571429,6.28571429 25.2063492,6.72603687 25.2063492,7.30184332 L25.2063492,26.2695853 C25.2063492,26.8453917 25.5571429,27.2857143 26.015873,27.2857143 Z M22.015873,27.2857143 C22.4746032,27.2857143 22.8253968,26.8453917 22.8253968,26.2695853 L22.8253968,7.30184332 C22.8253968,6.72603687 22.4746032,6.28571429 22.015873,6.28571429 C21.5571429,6.28571429 21.2063492,6.72603687 21.2063492,7.30184332 L21.2063492,26.2695853 C21.2063492,26.8453917 21.5571429,27.2857143 22.015873,27.2857143 Z M30.015873,27.2857143 C30.4746032,27.2857143 30.8253968,26.8453917 30.8253968,26.2695853 L30.8253968,7.30184332 C30.8253968,6.72603687 30.4746032,6.28571429 30.015873,6.28571429 C29.5571429,6.28571429 29.2063492,6.72603687 29.2063492,7.30184332 L29.2063492,26.2695853 C29.2063492,26.8453917 29.5571429,27.2857143 30.015873,27.2857143 Z\"\n              id=\"Shape\"\n            ></path>\n          </g>\n        </g>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"barcode-icon\": BarcodeIcon\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n\n@customElement(\"search-icon\")\nclass SearchIcon extends LitElement {\n  static override styles = css`\n    svg,\n    svg path {\n      fill: #ffffff;\n    }\n  `\n  override render() {\n    return html`\n      <svg\n        width=\"16px\"\n        height=\"16px\"\n        viewBox=\"0 0 16 16\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n      >\n        <title>Shape</title>\n        <g id=\"Icons\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n          <g id=\"Search\" fill=\"#000000\" fill-rule=\"nonzero\">\n            <path\n              d=\"M6.66263618,0 C2.99085545,0 0,2.99085545 0,6.66263618 C0,10.334417 2.99085545,13.3252724 6.66263618,13.3252724 C8.25934227,13.3252724 9.72570654,12.7582727 10.874932,11.8170701 L14.8529942,15.7951322 C15.0201041,15.9691875 15.2682543,16.0393016 15.5017411,15.9784339 C15.7352279,15.9175662 15.9175662,15.7352279 15.9784339,15.5017411 C16.0393016,15.2682543 15.9691875,15.0201041 15.7951322,14.8529942 L11.8170701,10.874932 C12.7582727,9.72570654 13.3252724,8.25934227 13.3252724,6.66263618 C13.3252724,2.99085545 10.334417,0 6.66263618,0 Z M6.66263618,1.33252724 C9.61426595,1.33252724 11.9927451,3.71100667 11.9927451,6.66263618 C11.9927451,9.61426595 9.61426595,11.9927451 6.66263618,11.9927451 C3.71100667,11.9927451 1.33252724,9.61426595 1.33252724,6.66263618 C1.33252724,3.71100667 3.71100667,1.33252724 6.66263618,1.33252724 Z\"\n              id=\"Shape\"\n            ></path>\n          </g>\n        </g>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"search-icon\": SearchIcon\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement } from \"lit/decorators.js\"\n\n@customElement(\"close-icon\")\nexport class CloseIcon extends LitElement {\n  static override styles = css``\n\n  override render() {\n    return html`\n      <svg\n        width=\"12px\"\n        height=\"12px\"\n        viewBox=\"0 0 12 12\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n      >\n        <title>Close</title>\n        <g id=\"Close\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n          <g id=\"close\" transform=\"translate(0, 0.1021)\" fill=\"#000000\" fill-rule=\"nonzero\">\n            <path\n              d=\"M0.752398486,0.000327615426 C0.447676997,0.000407642063 0.173386346,0.185108686 0.0587220133,0.467433469 C-0.0559423192,0.749758252 0.0118849522,1.07340821 0.230256049,1.28593881 L4.94270174,5.9983842 L0.230256049,10.7108297 C0.0346299462,10.8986525 -0.0441726876,11.1775583 0.0242395587,11.439983 C0.092651805,11.7024077 0.29758879,11.9073446 0.560013509,11.9757568 C0.822438228,12.044169 1.10134403,11.9653663 1.28916672,11.7697401 L6.00161211,7.05729458 L10.7140577,11.7697401 C10.9018799,11.9653685 11.1807868,12.0441728 11.4432128,11.9757609 C11.7056389,11.907349 11.9105769,11.702411 11.9789888,11.4399849 C12.0474007,11.1775588 11.9685964,10.898652 11.772968,10.7108297 L7.06052249,5.9983842 L11.772968,1.28593881 C11.9944461,1.07065294 12.0610395,0.741480633 11.9406599,0.457035041 C11.8202802,0.172589449 11.5376228,-0.00877712235 11.2288872,0.000327615426 C11.0343388,0.00612451054 10.8496893,0.0874332576 10.7140577,0.22702814 L6.00161211,4.93947383 L1.28916672,0.22702814 C1.14818126,0.0821025075 0.954587359,0.000339401564 0.752398486,0.000327615426 Z\"\n              id=\"Path\"\n            ></path>\n          </g>\n        </g>\n      </svg>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"close-icon\": CloseIcon\n  }\n}\n","import { LitElement } from \"lit\"\nimport type { Constructor } from \".\"\n\n/**\n * Interface for the ConsoleLogMixin.\n */\nexport interface ConsoleLogMixinInterface {\n  lastLogTime: Record<string, number>\n  logToConsole(id: string, message: string, time?: number): void\n}\n\n/**\n * Mixin that adds console logging functionality to a LitElement.\n */\nexport const ConsoleLogMixin = <T extends Constructor<LitElement>>(\n  superClass: T\n): Constructor<ConsoleLogMixinInterface> & T =>\n  class extends superClass {\n    lastLogTime: Record<string, number> = {}\n\n    logToConsole(id: string, message: string, time: number = 30000) {\n      const now = Date.now()\n      if (now - this.lastLogTime[id] >= time) {\n        console.log(message)\n        this.lastLogTime[id] = now\n      }\n    }\n  } as Constructor<ConsoleLogMixinInterface> & T\n","import { localized, msg } from \"@lit/localize\"\nimport { LitElement, html, css } from \"lit\"\nimport { customElement, property, query, state } from \"lit/decorators.js\"\nimport { BASE } from \"../../styles/base\"\nimport \"../icons/barcode\"\nimport \"../icons/search\"\nimport \"../icons/close\"\nimport { ButtonType, getButtonClasses } from \"../../styles/buttons\"\nimport { EventType } from \"../../constants\"\nimport { type StyleInfo, styleMap } from \"lit-html/directives/style-map.js\"\nimport { ConsoleLogMixin } from \"../../mixins/console-log-mixin\"\n\nexport enum BarcodeScannerState {\n  EXITED = \"exited\",\n  DETECTED = \"detected\",\n  DETECTOR_AVAILABLE = \"detector-available\",\n  DETECTOR_NOT_AVAILABLE = \"detector-not-available\",\n  STARTED = \"started\",\n  NO_PERMISSION = \"no-permission\",\n}\n\ninterface BarcodeDetector {\n  detect(video: ImageBitmap): Promise<{ rawValue: string }[]>\n}\n\n/**\n * BarcodeScanner is a custom web component that allows users to scan barcodes using their device's camera.\n * It uses the BarcodeDetector API to detect barcodes in real-time and dispatches custom events with the detected barcode data.\n * The component provides a user interface with an overlay that guides the user to scan a barcode and displays the detected barcode value.\n * @fires barcode-scanner-state - Indicates the state of the barcode scanner.\n * @slot message-before-scanning - The message to display before scanning.\n */\n@customElement(\"barcode-scanner\")\n@localized()\nexport class BarcodeScanner extends ConsoleLogMixin(LitElement) {\n  /**\n   * Static styles for the BarcodeScanner component.\n   * These styles define the appearance of the component, including the video element, overlay, and buttons.\n   */\n  static override styles = [\n    BASE,\n    getButtonClasses([ButtonType.White]),\n    css`\n      :host {\n        width: 100%;\n      }\n      .barcode-scanner {\n        display: block;\n        position: relative;\n        width: 100%;\n      }\n      .barcode-scanner video {\n        display: block;\n        background-color: black;\n        border-radius: 8px;\n        width: 100%;\n        height: 100%;\n      }\n      .overlay-wrapper {\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        position: absolute;\n        cursor: pointer;\n        z-index: 1;\n      }\n      .centered-overlay {\n        position: relative;\n        display: flex;\n        flex-direction: column;\n        justify-content: center;\n        align-items: center;\n        max-width: 100%;\n        width: 100%;\n        height: 100%;\n      }\n\n      .video-frame {\n        border: 3px solid #fff;\n        border-radius: 8px;\n        box-sizing: border-box;\n      }\n      .cta-overlay-wrapper {\n        width: 100%;\n        height: 100%;\n        padding: 10%;\n        cursor: pointer;\n        box-sizing: border-box;\n      }\n\n      .cta-exit-button {\n        position: absolute;\n        display: flex;\n        align-items: baseline;\n        justify-content: center;\n\n        top: 3px;\n        left: 3px;\n        z-index: 2;\n      }\n\n      .cta-overlay-text {\n        text-align: center;\n        color: white;\n      }\n      .cta-overlay-icon {\n        display: flex;\n        justify-content: center;\n      }\n      .cta-overlay-button {\n        z-index: 2;\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        width: 70px;\n        height: 70px;\n        border-radius: 50%;\n        border: none;\n        margin-top: 1rem;\n        cursor: pointer;\n        margin-bottom: 1rem;\n        background-color: transparent;\n      }\n      .cta-overlay-button.start-scanning {\n        background-color: #4c4c4d;\n      }\n\n      .cta-overlay {\n        position: relative;\n      }\n\n      .cta-overlay-frame {\n        width: 15%;\n        height: 15%;\n        position: absolute;\n      }\n\n      .cta-overlay-frame.left-top-border {\n        top: 40px;\n        left: 0px;\n        border-left: 2px solid white;\n        border-top: 2px solid white;\n        border-radius: 8px 0 0 0;\n      }\n\n      .cta-overlay-frame.left-bottom-border {\n        left: 0px;\n        bottom: 40px;\n        border-left: 2px solid white;\n        border-bottom: 2px solid white;\n        border-radius: 0 0 0 8px;\n      }\n      .cta-overlay-frame.right-bottom-border {\n        right: 0px;\n        bottom: 40px;\n        border-right: 2px solid white;\n        border-bottom: 2px solid white;\n        border-radius: 0 0 8px 0;\n      }\n\n      .cta-overlay-frame.right-top-border {\n        right: 0px;\n        top: 40px;\n        border-right: 2px solid white;\n        border-top: 2px solid white;\n        border-radius: 0 8px 0 0;\n      }\n    `,\n  ]\n\n  /**\n   * The style information for the wrapper element of the BarcodeScanner component.\n   * This property is reflected as an attribute on the component and can be used to customize the size and appearance of the component.\n   */\n  @property({ type: Object, attribute: \"wrapper-style\", reflect: true })\n  wrapperStyle: StyleInfo = {\n    height: \"300px\",\n    width: \"100%\",\n    \"max-width\": \"100%\",\n  }\n\n  /**\n   * A boolean property that indicates whether the barcode scanner should be running.\n   * When set to true, the component will attempt to start the camera and detect barcodes.\n   */\n  @property({ type: Boolean, attribute: \"run-scanner\", reflect: true })\n  runScanner = false\n\n  /**\n   * The barcode detected by the scanner\n   */\n  /**\n   * The barcode detected by the scanner.\n   * This state property is updated whenever a barcode is successfully detected.\n   */\n  @state()\n  barcode = \"\"\n\n  /**\n   * A reference to the video element used for displaying the camera feed.\n   * This query selector is used to access the video element within the component's template.\n   */\n  @query(\"video\")\n  private video!: HTMLVideoElement\n\n  /**\n   * The media stream used for the camera feed.\n   * This state property is updated when the camera is started and cleared when the camera is stopped.\n   */\n  @state()\n  private stream: MediaStream | null = null\n\n  /**\n   * The BarcodeDetector instance used for detecting barcodes.\n   * This state property is initialized when the component is constructed and used for barcode detection.\n   */\n  @state()\n  private codeReader: BarcodeDetector | null = null\n\n  /**\n   * A function that detects barcodes in an image bitmap.\n   * This state property is updated when the BarcodeDetector is available and used for barcode detection.\n   */\n  @state()\n  private detectFn?: (imageData: ImageBitmap) => Promise<string | undefined>\n\n  /**\n   * A getter that returns whether the video is currently playing.\n   * This getter is used to determine the state of the video element and update the component's UI accordingly.\n   */\n  get isVideoPlaying() {\n    return this.stream !== null\n  }\n\n  get canDetect() {\n    return this.detectFn !== undefined\n  }\n\n  /**\n   * The constructor for the BarcodeScanner component.\n   * This constructor initializes the BarcodeDetector and sets up the component's state.\n   */\n  constructor() {\n    super()\n    this.setupBarcodeDetector()\n  }\n\n  /**\n   * This lifecycle method is used to start the barcode scanner if the runScanner property is set to true.\n   */\n  override async firstUpdated() {\n    if (this.runScanner) {\n      await this.askPermission()\n    }\n  }\n\n  /**\n   * A lifecycle method that is called when an attribute on the component is changed.\n   * This method is used to handle changes to the run-scanner attribute and start or stop the barcode scanner accordingly.\n   */\n  override attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n    super.attributeChangedCallback(name, _old, value)\n    // if first update not run yet, do nothing\n    if (!this.hasUpdated) {\n      return\n    }\n    if (name === \"run-scanner\") {\n      if (this.runScanner) {\n        this.askPermission()\n      } else if (this.stream) {\n        this.stopVideo()\n      }\n    }\n  }\n\n  /**\n   * A private method that sets up the BarcodeDetector instance.\n   * This method is called when the component is constructed and initializes the BarcodeDetector and detectFn properties.\n   */\n  private setupBarcodeDetector() {\n    try {\n      // Remove the type assertion for BarcodeDetector to avoid TypeScript error\n      // @ts-ignore\n      this.codeReader = new BarcodeDetector({ formats: [\"ean_13\", \"ean_8\"] })\n      this.detectFn = this.detectWithBarcodeDetector\n      this.sendBarcodeStateEvent({ state: BarcodeScannerState.DETECTOR_AVAILABLE })\n    } catch (error) {\n      this.sendBarcodeStateEvent({ state: BarcodeScannerState.DETECTOR_NOT_AVAILABLE })\n      console.warn(\"BarcodeDetector not available:\", error)\n    }\n  }\n\n  /**\n   * A private method that detects barcodes in an image bitmap using the BarcodeDetector.\n   * This method is called when a video frame is captured and used to detect barcodes in the frame.\n   */\n  private async detectWithBarcodeDetector(imageData: ImageBitmap): Promise<string | undefined> {\n    try {\n      // Type assertion for BarcodeDetector\n      const detector = this.codeReader\n      if (detector) {\n        const barcodes = await detector.detect(imageData)\n        if (barcodes.length > 0) {\n          return barcodes[0].rawValue\n        }\n      }\n    } catch (error) {\n      console.error(\"Error detecting barcode:\", error)\n    }\n    return undefined\n  }\n\n  /**\n   * A private method that asks for camera permission and starts the barcode scanner if permission is granted.\n   * This method is called when the user clicks the start scanning button or when the runScanner property is set to true.\n   */\n  private async askPermission() {\n    // If it can't detect, don't ask for permission\n    if (!this.canDetect) {\n      this.sendBarcodeStateEvent({\n        state: BarcodeScannerState.DETECTOR_NOT_AVAILABLE,\n      })\n      return\n    }\n    try {\n      const permissionStatus = await navigator.permissions.query({ name: \"camera\" })\n\n      if ([\"granted\", \"prompt\"].includes(permissionStatus.state)) {\n        await this.startCamera()\n        return\n      } else {\n        console.warn(\"Camera permission denied. Please enable it in your browser settings.\")\n      }\n    } catch (error) {\n      console.error(\"Permission query error:\", error)\n    }\n    this.sendBarcodeStateEvent({\n      barcode: this.barcode,\n      state: BarcodeScannerState.NO_PERMISSION,\n    })\n  }\n\n  /**\n   * A private method that starts the camera and sets up the video element.\n   * This method is called when camera permission is granted and used to start the camera feed.\n   */\n  private async startCamera() {\n    try {\n      // Request the camera stream with specified constraints\n      this.stream = await navigator.mediaDevices.getUserMedia({\n        video: {\n          facingMode: \"environment\",\n          width: { ideal: 640, max: 1280 },\n          height: { ideal: 480, max: 720 },\n        },\n      })\n\n      // Set the video source to the camera stream and play the video\n      if (this.video) {\n        this.video.srcObject = this.stream\n        await this.video.play()\n        this.sendBarcodeStateEvent({\n          state: BarcodeScannerState.STARTED,\n        })\n\n        // Set up video frame capture\n        this.setupFrameCapture()\n      }\n    } catch (err) {\n      console.error(\"Error accessing camera: \", err)\n    }\n  }\n\n  /**\n   * A private method that stops the video and clears the media stream.\n   * This method is called when the barcode scanner is stopped or when the component is disconnected.\n   */\n  private stopVideo() {\n    if (this.stream) {\n      this.stream.getTracks().forEach((track) => track.stop())\n      // clean video\n      this.video.srcObject = null\n      this.stream = null\n    }\n  }\n\n  /**\n   * A private method that sends a custom event with the barcode scanner's state.\n   * This method is called whenever the barcode scanner's state changes and used to notify other components of the state change.\n   */\n  private sendBarcodeStateEvent(detail: { barcode?: string; state: BarcodeScannerState }) {\n    this.dispatchEvent(new CustomEvent(EventType.BARCODE_SCANNER_STATE, { detail }))\n  }\n\n  /**\n   * A private method that handles the exit button click event.\n   * This method is called when the user clicks the exit button and used to stop the barcode scanner and clear the video element.\n   */\n  private exit(event: Event) {\n    event.stopPropagation()\n    this.stopVideo()\n    this.sendBarcodeStateEvent({\n      state: BarcodeScannerState.EXITED,\n    })\n  }\n\n  /**\n   * A private method that sets up the video frame capture for barcode detection.\n   * This method is called when the camera is started and used to capture video frames and detect barcodes in the frames.\n   */\n  private setupFrameCapture() {\n    const video = this.video\n    // Process video frames for barcode detection\n    const processFrame = async () => {\n      // Check if the video is paused or ended\n      if (video.paused || video.ended) {\n        requestAnimationFrame(processFrame)\n        return\n      }\n\n      let imageBitmap: ImageBitmap | undefined\n      try {\n        // Create an image bitmap from the current video frame\n        imageBitmap = await createImageBitmap(video, 0, 0, video.videoWidth, video.videoHeight)\n      } catch (e) {\n        this.logToConsole(\"image-bitmap\", `Error creating image bitmap: ${e}`)\n      }\n\n      if (imageBitmap) {\n        try {\n          // Detect barcodes in the image bitmap\n          const result = await this.detectFn!(imageBitmap)\n          if (result) {\n            this.barcode = result\n            this.sendBarcodeStateEvent({\n              barcode: this.barcode,\n              state: BarcodeScannerState.DETECTED,\n            })\n\n            // Stop the video after detecting a barcode\n            this.stopVideo()\n            return\n          }\n        } catch (error) {\n          console.error(\"Barcode detection error:\", error)\n        }\n      }\n\n      // Continue processing frames if no barcode is detected\n      requestAnimationFrame(processFrame)\n    }\n\n    requestAnimationFrame(processFrame)\n  }\n\n  /**\n   * A lifecycle method that is called when the component is disconnected from the DOM.\n   * This method is used to stop the barcode scanner and clear the video element when the component is removed from the DOM.\n   */\n  override disconnectedCallback() {\n    super.disconnectedCallback()\n    this.stopVideo()\n  }\n\n  /**\n   * A private method that renders the overlay for the barcode scanner.\n   * This method is called whenever the component's UI needs to be updated and used to render the overlay based on the component's state.\n   */\n  private renderOverlay() {\n    if (!this.canDetect) {\n      return html` <div class=\"cta-overlay-wrapper\">\n        <div class=\"centered-overlay\">\n          <div class=\"cta-overlay\">\n            <div class=\"cta-overlay-text\">\n              ${msg(\"Your browser does not support barcode scanning.\")}\n            </div>\n          </div>\n        </div>\n      </div>`\n    }\n    if (this.isVideoPlaying) {\n      return html`\n        <div class=\"cta-overlay-wrapper\" @click=${this.askPermission}>\n          <div class=\"cta-exit-button\">\n            <button class=\"button white-button small\" @click=${this.exit}>\n              <close-icon></close-icon><span>${msg(\"Close\")}</span>\n            </button>\n          </div>\n          <div class=\"centered-overlay\">\n            <div class=\"cta-overlay-frame right-top-border\"></div>\n            <div class=\"cta-overlay-frame left-top-border\"></div>\n            <div class=\"cta-overlay-frame right-bottom-border\"></div>\n            <div class=\"cta-overlay-frame left-bottom-border\"></div>\n            <div class=\"cta-overlay\">\n              <div class=\"cta-overlay-icon\">\n                <button class=\"cta-overlay-button\">\n                  <search-icon></search-icon>\n                </button>\n              </div>\n            </div>\n          </div>\n        </div>\n      `\n    }\n    return html`\n      <div class=\"cta-overlay-wrapper\" @click=${this.askPermission}>\n        <div class=\"centered-overlay\">\n          <div class=\"cta-overlay\">\n            <div class=\"cta-overlay-icon\">\n              <button class=\"cta-overlay-button start-scanning\">\n                <barcode-icon></barcode-icon>\n              </button>\n            </div>\n            <div class=\"cta-overlay-text\">\n              <slot name=\"message-before-scanning\">\n                ${msg(\n                  \"Click to scan a barcode and find out its details (health, preferences, etc.)\"\n                )}\n              </slot>\n            </div>\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  /**\n   * A lifecycle method that renders the component's template.\n   * This method is called whenever the component's UI needs to be updated and used to render the component's template based on its state.\n   */\n  override render() {\n    return html`\n      <div class=\"barcode-scanner\" style=${styleMap(this.wrapperStyle)}>\n        <video width=\"100%\"></video>\n        <div class=\"overlay-wrapper\">${this.renderOverlay()}</div>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"barcode-scanner\": BarcodeScanner\n  }\n}\n","import { msg } from \"@lit/localize\"\nimport { LitElement, html, css } from \"lit-element\"\nimport { customElement, state } from \"lit/decorators.js\"\nimport { getButtonClasses, ButtonType } from \"../../styles/buttons\"\nimport { MODAL } from \"../../styles/modal\"\n\n/**\n * @customElement(\"delete-modal\")\n * @lit\n * @element delete-modal\n * @description A modal dialog for confirming deletion of an item.\n */\n@customElement(\"delete-modal\")\nexport class DeleteModal extends LitElement {\n  @state() open = true\n\n  static override styles = [\n    MODAL,\n    ...getButtonClasses([ButtonType.Danger, ButtonType.Chocolate]),\n    css`\n      .overlay {\n        position: fixed;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0;\n        background: rgba(0, 0, 0, 0.5);\n        z-index: 1000;\n        animation: fadeIn 0.2s ease-out;\n      }\n\n      .modal {\n        position: fixed;\n        top: 50%;\n        left: 50%;\n        transform: translate(-50%, -50%);\n        background: white;\n        border-radius: 12px;\n        padding: 24px;\n        min-width: 400px;\n        max-width: 500px;\n        box-shadow:\n          0 20px 25px -5px rgba(0, 0, 0, 0.1),\n          0 10px 10px -5px rgba(0, 0, 0, 0.04);\n        z-index: 1001;\n        animation: slideIn 0.3s ease-out;\n      }\n\n      @keyframes fadeIn {\n        from {\n          opacity: 0;\n        }\n        to {\n          opacity: 1;\n        }\n      }\n\n      @keyframes slideIn {\n        from {\n          opacity: 0;\n          transform: translate(-50%, -50%) scale(0.95);\n        }\n        to {\n          opacity: 1;\n          transform: translate(-50%, -50%) scale(1);\n        }\n      }\n\n      .modal-title {\n        font-size: 20px;\n        font-weight: 600;\n        color: #1f2937;\n        margin: 0 0 24px 0;\n        text-align: center;\n        margin-bottom: 12px;\n      }\n\n      .modal-content {\n        margin-bottom: 12px;\n      }\n\n      .modal-message {\n        font-size: 16px;\n        color: #6b7280;\n        line-height: 1.5;\n        margin: 0;\n      }\n\n      .modal-buttons {\n        display: flex;\n        justify-content: flex-end;\n        gap: 12px;\n      }\n\n      .button {\n        padding: 12px 24px;\n        border: none;\n        border-radius: 8px;\n        font-size: 14px;\n        font-weight: 500;\n        cursor: pointer;\n        transition: all 0.2s ease;\n        min-width: 90px;\n      }\n\n      .button:focus {\n        outline: none;\n        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n      }\n\n      .chocolate-button {\n        background: #341100;\n        border: 1px solid #341100;\n        color: white;\n      }\n\n      .danger-button {\n        border: 1px solid #ff5252;\n        background: #ff5252;\n        color: white;\n      }\n\n      @media (max-width: 480px) {\n        .modal {\n          min-width: 320px;\n          margin: 16px;\n          padding: 24px;\n        }\n\n        .modal-buttons {\n          flex-direction: column-reverse;\n        }\n\n        .button {\n          width: 100%;\n          justify-content: center;\n        }\n      }\n    `,\n  ]\n\n  private handleDelete(event: Event) {\n    event.preventDefault()\n    this.dispatchEvent(\n      new CustomEvent(\"confirm-delete\", {\n        bubbles: true,\n        composed: true,\n      })\n    )\n    this.open = false\n  }\n\n  private handleCancel(event: Event) {\n    event.preventDefault()\n    this.open = false\n  }\n\n  private handleKeyDown(event: KeyboardEvent) {\n    if (event.key === \"Escape\") {\n      this.handleCancel(event)\n    }\n  }\n\n  override connectedCallback() {\n    super.connectedCallback()\n    document.addEventListener(\"keydown\", this.handleKeyDown.bind(this))\n  }\n\n  override disconnectedCallback() {\n    super.disconnectedCallback()\n    document.removeEventListener(\"keydown\", this.handleKeyDown.bind(this))\n  }\n\n  override render() {\n    if (!this.open) {\n      return null\n    }\n\n    return html`\n      <div class=\"overlay\" @click=\"${this.handleCancel}\"></div>\n      <div class=\"modal\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"modal-title\">\n        <h2 id=\"modal-title\" class=\"modal-title\">${msg(\"Confirm Delete\")}</h2>\n        <div class=\"modal-content\">\n          <p class=\"modal-message\">\n            ${msg(\"Are you sure you want to delete this item? This action cannot be undone.\")}\n          </p>\n        </div>\n        <div class=\"modal-buttons\">\n          <button\n            type=\"button\"\n            class=\"button chocolate-button\"\n            @click=\"${this.handleCancel}\"\n            aria-label=\"${msg(\"Cancel deletion\")}\"\n          >\n            ${msg(\"Cancel\")}\n          </button>\n          <button\n            class=\"button danger-button\"\n            @click=\"${this.handleDelete}\"\n            aria-label=\"${msg(\"Confirm deletion\")}\"\n          >\n            ${msg(\"Delete\")}\n          </button>\n        </div>\n      </div>\n    `\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement, state } from \"lit/decorators.js\"\nimport { localized, msg } from \"@lit/localize\"\nimport {\n  OpenFoodFactsSlackLink,\n  FolksnomyEngineDocumentationLink,\n  FolksnomyEnginePropertyLink,\n} from \"../../utils\"\n\n/**\n * New Key Modal Component\n * @element new-key-modal\n * @description A modal that provides instructions for creating a new key in the folksonomy editor\n */\n@customElement(\"new-key-modal\")\n@localized()\nexport class NewKeyModal extends LitElement {\n  @state()\n  private propertyName = \"\"\n  static override styles = css`\n    .modal-overlay {\n      position: fixed;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      background: rgba(0, 0, 0, 0.5);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      z-index: 10000;\n    }\n\n    .modal-content {\n      background: white;\n      padding: 2rem;\n      border-radius: 8px;\n      max-width: 600px;\n      width: 90%;\n      max-height: 80vh;\n      overflow-y: auto;\n      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n    }\n\n    .modal-header {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      margin-bottom: 1.5rem;\n      padding-bottom: 1rem;\n      border-bottom: 1px solid #e0e0e0;\n    }\n\n    .modal-title {\n      font-size: 1.5rem;\n      font-weight: 600;\n      color: #333;\n      margin: 0;\n    }\n\n    .close-button {\n      background: none;\n      border: none;\n      font-size: 1.5rem;\n      cursor: pointer;\n      color: #666;\n      padding: 0.5rem;\n      border-radius: 4px;\n      transition: background-color 0.2s;\n    }\n\n    .close-button:hover {\n      background-color: #f0f0f0;\n    }\n\n    .property-input-section {\n      margin-bottom: 1.5rem;\n      padding: 1rem;\n      border: 1px solid #ddd;\n      border-radius: 4px;\n    }\n\n    .property-input-container {\n      align-items: flex-end;\n    }\n\n    .input-group {\n      flex: 1;\n    }\n\n    .input-label {\n      display: block;\n      margin-bottom: 0.5rem;\n      font-weight: 500;\n    }\n\n    .property-input {\n      width: 100%;\n      padding: 0.5rem;\n      border: 1px solid #ddd;\n      border-radius: 4px;\n      font-size: 1rem;\n    }\n\n    .property-input:focus {\n      outline: none;\n      border-color: #007bff;\n    }\n\n    .create-wiki-button {\n      margin-top: 4px;\n      background: #007bff;\n      color: white;\n      border: none;\n      padding: 0.5rem 1rem;\n      border-radius: 4px;\n      cursor: pointer;\n    }\n\n    .create-wiki-button:hover:not(:disabled) {\n      background: #0056b3;\n    }\n\n    .create-wiki-button:disabled {\n      background: #ccc;\n      cursor: not-allowed;\n    }\n\n    .instruction-list {\n      margin: 1rem 0;\n      padding-left: 0;\n    }\n\n    .instruction-item {\n      margin-bottom: 1.5rem;\n      padding: 1rem;\n      border-left: 4px solid #007bff;\n      background: #f8f9fa;\n    }\n\n    .instruction-title {\n      font-weight: 600;\n      color: #007bff;\n      margin-bottom: 0.5rem;\n    }\n\n    .instruction-description {\n      color: #555;\n      margin-bottom: 0.5rem;\n    }\n\n    .instruction-link {\n      color: #007bff;\n      text-decoration: none;\n      font-weight: 500;\n    }\n\n    .instruction-link:hover {\n      text-decoration: underline;\n    }\n\n    .join-slack-discussion {\n      padding-top: 6px;\n    }\n\n    .instruction-button {\n      background: #007bff;\n      color: white;\n      border: none;\n      padding: 0.5rem 1rem;\n      border-radius: 4px;\n      cursor: pointer;\n      text-decoration: none;\n    }\n\n    .instruction-button:hover {\n      background: #0056b3;\n    }\n\n    @media (max-width: 768px) {\n      .modal-content {\n        width: 95%;\n        padding: 1rem;\n      }\n\n      .property-input-container {\n        flex-direction: column;\n        align-items: stretch;\n      }\n\n      .create-wiki-button {\n        margin-top: 0.5rem;\n      }\n    }\n  `\n\n  private handleClose() {\n    this.dispatchEvent(\n      new CustomEvent(\"close-modal\", {\n        bubbles: true,\n        composed: true,\n      })\n    )\n  }\n\n  private handlePropertyNameInput(e: Event) {\n    const input = e.target as HTMLInputElement\n    this.propertyName = input.value.trim()\n  }\n\n  private handleCreateWikiPage() {\n    if (!this.propertyName) return\n\n    const encodedPropertyName = encodeURIComponent(this.propertyName)\n    const wikiUrl = `https://wiki.openfoodfacts.org/Folksonomy/Property/${encodedPropertyName}?action=edit&section=new&nosummary=true&preload=Folksonomy/Property/property_template`\n    window.open(wikiUrl, \"_blank\")\n  }\n\n  override render() {\n    return html`\n      <div class=\"modal-overlay\" @click=${this.handleClose}>\n        <div class=\"modal-content\" @click=${(e: Event) => e.stopPropagation()}>\n          <div class=\"modal-header\">\n            <h2 class=\"modal-title\">${msg(\"Creating a New Property\")}</h2>\n            <button class=\"close-button\" @click=${this.handleClose}>×</button>\n          </div>\n\n          <div class=\"instruction-list\">\n            <div class=\"instruction-item\">\n              <div class=\"instruction-title\">1. ${msg(\"Check if a property already exists\")}</div>\n              <div class=\"instruction-description\">\n                ${msg(\"Search for your property concept in the existing properties database:\")}\n              </div>\n              <a href=${FolksnomyEnginePropertyLink} target=\"_blank\" class=\"instruction-link\">\n                ${msg(\"Browse and search existing properties\")}\n              </a>\n            </div>\n\n            <div class=\"instruction-item\">\n              <div class=\"instruction-title\">2. ${msg(\"Ask the community first\")}</div>\n              <div class=\"instruction-description\">\n                ${msg(\"Before creating a new property, discuss it with the community:\")}\n              </div>\n              <div class=\"instruction-description\">\n                ${msg(\"I would like to create a property to [describe your use case]...\")}\n              </div>\n              <div class=\"join-slack-discussion\">\n                <a class=\"instruction-button\" href=${OpenFoodFactsSlackLink} target=\"_blank\">\n                  ${msg(\"Join Slack Discussion\")}\n                </a>\n              </div>\n            </div>\n\n            <div class=\"instruction-item\">\n              <div class=\"instruction-title\">3. ${msg(\"Document the New Property\")}</div>\n              <div class=\"instruction-description\">\n                ${msg(\n                  \"Once you've verified that your property doesn't exist and the community agrees it's useful, you need to first document it in the wiki.\"\n                )}\n              </div>\n              <div class=\"property-input-section\">\n                <div class=\"property-input-container\">\n                  <div class=\"input-group\">\n                    <label class=\"input-label\">${msg(\"Property name:\")}</label>\n                    <input\n                      type=\"text\"\n                      class=\"property-input\"\n                      placeholder=\"${msg(\"Enter property name...\")}\"\n                      .value=\"${this.propertyName}\"\n                      @input=\"${this.handlePropertyNameInput}\"\n                    />\n                  </div>\n                  <button\n                    class=\"create-wiki-button\"\n                    @click=\"${this.handleCreateWikiPage}\"\n                    ?disabled=\"${!this.propertyName}\"\n                  >\n                    ${msg(\"Document the property\")}\n                  </button>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"instruction-item\">\n              <div class=\"instruction-title\">4. ${msg(\"Documentation and Guidelines\")}</div>\n              <div class=\"instruction-description\">\n                ${msg(\"Learn more about property creation and guidelines:\")}\n              </div>\n              <a href=${FolksnomyEngineDocumentationLink} target=\"_blank\" class=\"instruction-link\">\n                ${msg(\"Folksonomy Engine Documentation\")}\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"new-key-modal\": NewKeyModal\n  }\n}\n","import type {\n  FetchProductPropertiesResponse,\n  AddProductPropertyResponse,\n  DeleteProductPropertyResponse,\n  UpdateProductPropertyResponse,\n  AuthByCookieResponse,\n  ValueRenameRequest,\n  ValueDeleteRequest,\n  UserInfo,\n  PropertyRenameRequest,\n  PropertyDeleteRequest,\n  PropertyClashCheck,\n} from \"../types/folksonomy\"\n\nimport { folksonomyConfiguration, userInfo, userInfoLoading } from \"../signals/folksonomy\"\n\n// Constants for localStorage\nconst FOLKSONOMY_BEARER_TOKEN_KEY = \"folksonomy-bearer-token\"\nconst FOLKSONOMY_BEARER_DATE_KEY = \"folksonomy-token-date\"\n\n/**\n * Get the API URL for a given path with the current configuration\n * @param path\n * @returns {string}\n */\n\nconst getApiUrl = (path: string) => {\n  return `${folksonomyConfiguration.getItem(\"apiUrl\")}${path}`\n}\n\n/**\n * Get stored token from localStorage\n * @returns {string | null}\n */\nfunction getStoredToken(): string | null {\n  return localStorage.getItem(FOLKSONOMY_BEARER_TOKEN_KEY)\n}\n\n/**\n * Save token to localStorage\n * @param token\n */\nfunction saveTokenToStorage(token: string) {\n  localStorage.setItem(FOLKSONOMY_BEARER_TOKEN_KEY, token)\n  localStorage.setItem(FOLKSONOMY_BEARER_DATE_KEY, new Date().getTime().toString())\n}\n\n/**\n * Clear token from localStorage\n */\nfunction clearStoredToken() {\n  localStorage.removeItem(FOLKSONOMY_BEARER_TOKEN_KEY)\n  localStorage.removeItem(FOLKSONOMY_BEARER_DATE_KEY)\n}\n\n/**\n * Authenticate by cookie and get access token\n * @returns {Promise<AuthByCookieResponse>}\n */\nasync function authByCookie(): Promise<AuthByCookieResponse> {\n  try {\n    const response = await fetch(getApiUrl(\"/auth_by_cookie\"), {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n      credentials: \"include\",\n    })\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n    const data: AuthByCookieResponse = await response.json()\n\n    // Save token to localStorage\n    if (data.access_token) {\n      saveTokenToStorage(data.access_token)\n    }\n\n    return data\n  } catch (error) {\n    console.error(\"Error authenticating by cookie:\", error)\n    clearStoredToken()\n    throw error\n  }\n}\n\n/**\n * Get valid access token - check localStorage first, then authenticate if needed\n * @returns {Promise<string>}\n */\nasync function getValidToken(): Promise<string> {\n  const storedToken = getStoredToken()\n  if (storedToken) {\n    return storedToken\n  }\n\n  const authResponse = await authByCookie()\n  return authResponse.access_token\n}\n\n/**\n * Make authenticated request with retry logic\n * @param url\n * @param options\n * @returns {Promise<Response>}\n */\nasync function makeAuthenticatedRequest(url: string, options: RequestInit = {}): Promise<Response> {\n  const token = await getValidToken()\n\n  const requestOptions = {\n    ...options,\n    headers: {\n      ...options.headers,\n      Authorization: `Bearer ${token}`,\n    },\n  }\n\n  const response = await fetch(url, requestOptions)\n\n  // If auth fails (401/403), try once more with fresh token\n  if (response.status === 401 || response.status === 403) {\n    console.error(\"Auth failed, retrying with fresh token...\")\n    clearStoredToken()\n    const newToken = await getValidToken()\n\n    const retryOptions = {\n      ...options,\n      headers: {\n        ...options.headers,\n        Authorization: `Bearer ${newToken}`,\n      },\n    }\n\n    return fetch(url, retryOptions)\n  }\n\n  return response\n}\n\nasync function fetchProductProperties(product: string): Promise<FetchProductPropertiesResponse> {\n  try {\n    const response = await fetch(getApiUrl(`/product/${product}`))\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n    const data: FetchProductPropertiesResponse = await response.json()\n    return data\n  } catch (error) {\n    console.error(\"Error fetching product properties:\", error)\n    throw error\n  }\n}\n\nasync function addProductProperty(\n  product: string,\n  k: string,\n  v: string,\n  version: number\n): Promise<AddProductPropertyResponse> {\n  try {\n    const response = await makeAuthenticatedRequest(getApiUrl(\"/product\"), {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n      body: JSON.stringify({ product, ...{ k, v, version } }),\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n    return { key: k, value: v, version: 1 }\n  } catch (error) {\n    console.error(\"Error adding product property:\", error)\n    throw error\n  }\n}\n\nasync function deleteProductProperty(\n  product: string,\n  k: string,\n  version: number\n): Promise<DeleteProductPropertyResponse> {\n  try {\n    const response = await makeAuthenticatedRequest(\n      getApiUrl(`/product/${product}/${k}?version=${version}`),\n      {\n        method: \"DELETE\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n        } as HeadersInit,\n      }\n    )\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n    return { success: true }\n  } catch (error) {\n    console.error(\"Error deleting product property:\", error)\n    throw error\n  }\n}\n\nasync function updateProductProperty(\n  product: string,\n  k: string,\n  v: string,\n  version: number\n): Promise<UpdateProductPropertyResponse> {\n  try {\n    const response = await makeAuthenticatedRequest(getApiUrl(\"/product\"), {\n      method: \"PUT\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n      body: JSON.stringify({ product, ...{ k, v, version: version + 1 } }),\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n    return { key: k, value: v, version: version + 1 }\n  } catch (error) {\n    console.error(\"Error updating product property:\", error)\n    throw error\n  }\n}\n\nasync function fetchKeys(): Promise<{ k: string; count: number; values: number }[]> {\n  try {\n    const response = await fetch(getApiUrl(\"/keys\"), {\n      method: \"GET\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    const data: { k: string; count: number; values: number }[] = await response.json()\n    return data\n  } catch (error) {\n    console.error(\"Error fetching keys:\", error)\n    throw error\n  }\n}\n\nasync function fetchProductsProperties(\n  propertyName: string\n): Promise<{ k: string; v: string; product: string }[]> {\n  try {\n    let url = `/products?k=${propertyName}`\n\n    const response = await fetch(getApiUrl(url), {\n      method: \"GET\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    const data = await response.json()\n    return data || []\n  } catch (error) {\n    console.error(\"Error fetching property products:\", error)\n    throw error\n  }\n}\n\nasync function fetchValues(key: string): Promise<{ v: string; product_count: number }[]> {\n  try {\n    const response = await fetch(getApiUrl(`/values/${key}`), {\n      method: \"GET\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    const data: { v: string; product_count: number }[] = await response.json()\n    return data\n  } catch (error) {\n    console.error(\"Error fetching values:\", error)\n    throw error\n  }\n}\n\nasync function getUserInfo(): Promise<UserInfo> {\n  try {\n    const response = await makeAuthenticatedRequest(getApiUrl(\"/user/me\"), {\n      method: \"GET\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    const data: UserInfo = await response.json()\n    return data\n  } catch (error) {\n    console.error(\"Error fetching user info:\", error)\n    throw error\n  }\n}\n\n/**\n * Fetch user info and update the shared signal\n * Only fetches if not already loading or if force is true\n */\nasync function fetchUserInfo(force: boolean = false): Promise<UserInfo | null> {\n  // Don't fetch if already loading (unless forced)\n  if (userInfoLoading.get() && !force) {\n    return userInfo.get()\n  }\n\n  // Don't fetch if we already have user info (unless forced)\n  if (userInfo.get() && !force) {\n    return userInfo.get()\n  }\n\n  userInfoLoading.set(true)\n\n  try {\n    const fetchedUserInfo = await getUserInfo()\n    userInfo.set(fetchedUserInfo)\n    return fetchedUserInfo\n  } catch (error) {\n    console.error(\"Error fetching user info:\", error)\n    // User might not be authenticated, which is fine\n    userInfo.set(null)\n    return null\n  } finally {\n    userInfoLoading.set(false)\n  }\n}\n\n/**\n * Clear user info (useful for logout)\n */\nexport function clearUserInfo() {\n  userInfo.set(null)\n  userInfoLoading.set(false)\n}\n\nasync function replaceValue(request: ValueRenameRequest): Promise<{ success: boolean }> {\n  try {\n    const response = await makeAuthenticatedRequest(getApiUrl(\"/admin/value/replace\"), {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n      body: JSON.stringify(request),\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    return { success: true }\n  } catch (error) {\n    console.error(\"Error replacing value:\", error)\n    throw error\n  }\n}\n\nasync function deleteValue(request: ValueDeleteRequest): Promise<{ success: boolean }> {\n  try {\n    const response = await makeAuthenticatedRequest(getApiUrl(\"/admin/value\"), {\n      method: \"DELETE\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n      body: JSON.stringify(request),\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    return { success: true }\n  } catch (error) {\n    console.error(\"Error deleting value:\", error)\n    throw error\n  }\n}\n\nasync function checkPropertyClash(request: PropertyRenameRequest): Promise<PropertyClashCheck> {\n  try {\n    const response = await makeAuthenticatedRequest(getApiUrl(\"/admin/property/check-clash\"), {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n      body: JSON.stringify(request),\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    const data: PropertyClashCheck = await response.json()\n    return data\n  } catch (error) {\n    console.error(\"Error checking property clash:\", error)\n    throw error\n  }\n}\n\nasync function renameProperty(request: PropertyRenameRequest): Promise<{ success: boolean }> {\n  try {\n    const response = await makeAuthenticatedRequest(getApiUrl(\"/admin/property/rename\"), {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n      body: JSON.stringify(request),\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    return { success: true }\n  } catch (error) {\n    console.error(\"Error renaming property:\", error)\n    throw error\n  }\n}\n\nasync function deleteProperty(request: PropertyDeleteRequest): Promise<{ success: boolean }> {\n  try {\n    const response = await makeAuthenticatedRequest(getApiUrl(\"/admin/property\"), {\n      method: \"DELETE\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      } as HeadersInit,\n      body: JSON.stringify(request),\n    })\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    return { success: true }\n  } catch (error) {\n    console.error(\"Error deleting property:\", error)\n    throw error\n  }\n}\n\nexport default {\n  fetchProductProperties,\n  addProductProperty,\n  deleteProductProperty,\n  updateProductProperty,\n  fetchKeys,\n  fetchProductsProperties,\n  fetchValues,\n  authByCookie,\n  getUserInfo,\n  fetchUserInfo,\n  replaceValue,\n  deleteValue,\n  checkPropertyClash,\n  renameProperty,\n  deleteProperty,\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport \"./delete-modal\"\nimport \"./new-key-modal\"\nimport \"../shared/autocomplete-input\"\nimport folksonomyApi from \"../../api/folksonomy\"\nimport { msg } from \"@lit/localize\"\nimport { getButtonClasses, ButtonType } from \"../../styles/buttons\"\nimport { FOLKSONOMY_INPUT } from \"../../styles/folksonomy-input\"\nimport type {\n  AutocompleteSuggestion,\n  AutocompleteInputChangeEvent,\n  AutocompleteSuggestionSelectEvent,\n} from \"../../types\"\n\n/**\n * FolksonomyEditorRow Component\n * @element folksonomy-editor-row\n * @description A component for adding and editing product properties in a table row format.\n * @fires update-row - Fired when a row is updated.\n * @fires delete-row - Fired when a row is deleted.\n * @fires add-row - Fired when a new row is added.\n */\n@customElement(\"folksonomy-editor-row\")\nexport class FolksonomyEditorRow extends LitElement {\n  /**\n   * Input value for the key field.\n   * @private\n   */\n  @state() private keyInput = \"\"\n\n  /**\n   * Input value for the value field.\n   * @private\n   */\n  @state() private valueInput = \"\"\n\n  /**\n   * Suggestions for the key field.\n   * @private\n   */\n  @state() private keySuggestions: AutocompleteSuggestion[] = []\n\n  /**\n   * Suggestions for the value field.\n   * @private\n   */\n  @state() private valueSuggestions: AutocompleteSuggestion[] = []\n\n  /**\n   * Temporary value used during editing.\n   * @private\n   */\n  @state() private tempValue = \"\"\n\n  /**\n   * Product code associated with the row.\n   */\n  @property({ type: String, attribute: \"product-code\" }) productCode = \"\"\n\n  /**\n   * Version number of the product property.\n   */\n  @property({ type: Number }) version = 1\n\n  /**\n   * Row number in the table.\n   */\n  @property({ type: Number, attribute: \"row-number\" }) rowNumber = 1\n\n  /**\n   * Key of the product property.\n   */\n  @property({ type: String }) key = \"\"\n\n  /**\n   * Value of the product property.\n   */\n  @property({ type: String }) value = \"\"\n\n  /**\n   * Page type (e.g., view or edit).\n   */\n  @property({ type: String, attribute: \"page-type\" }) pageType = \"view\"\n\n  /**\n   * Indicates whether the row is empty.\n   */\n  @property({ type: Boolean }) empty = false\n\n  /**\n   * Indicates whether the row is editable.\n   * @private\n   */\n  @state() editable = false\n\n  /**\n   * Indicates whether the new key modal is open.\n   * @private\n   */\n  @state() showNewKeyModal = false\n\n  override connectedCallback() {\n    super.connectedCallback()\n    if (this.pageType === \"edit\") {\n      this.editable = true\n      this.tempValue = this.value\n    }\n\n    folksonomyApi\n      .fetchKeys()\n      .then((keys) => {\n        this.keySuggestions = keys.map((key) => ({\n          value: key.k,\n        }))\n      })\n      .catch((error) => console.error(\"Error fetching keys:\", error))\n  }\n\n  /**\n   * Fetches values for a given key and updates suggestions.\n   * @param key - The key to fetch values for.\n   * @private\n   */\n  private async fetchValuesForKey(key: string) {\n    try {\n      const values = await folksonomyApi.fetchValues(key)\n      this.valueSuggestions = values.map((value) => ({\n        value: value.v,\n      }))\n    } catch (error) {\n      console.error(\"Error fetching values for key:\", error)\n    }\n  }\n\n  /**\n   * Handles input changes for the key field.\n   * @param e - The input event.\n   * @private\n   */\n  private onKeyInput(e: AutocompleteInputChangeEvent) {\n    const value = (e.target as HTMLInputElement).value\n    this.keyInput = value\n    this.key = value\n\n    if (e.detail.matching) {\n      this.fetchValuesForKey(value)\n    }\n  }\n\n  /**\n   * Handles input changes for the value field.\n   * @param e - The input event.\n   * @private\n   */\n  private onValueInput(e: AutocompleteInputChangeEvent) {\n    const value = e.detail.value\n    this.valueInput = value\n    this.value = value\n\n    // In case of input value match exactly with only one suggestion, fetch values for the key\n    if (e.detail.matching) {\n      this.fetchValuesForKey(this.keyInput)\n    }\n  }\n\n  /**\n   * Selects a key suggestion and updates the key field.\n   * @param suggestion - The selected key suggestion.\n   * @private\n   */\n  private selectKeySuggestion(suggestion: string) {\n    // Check if this is the \"not found\" option\n    if (suggestion === \"__NOT_FOUND__\") {\n      this.showNewKeyModal = true\n      return\n    }\n\n    const hasChanged = this.keyInput !== suggestion\n    // Avoid calling fetchValuesForKey if the key has not changed\n    if (!hasChanged) {\n      return\n    }\n    this.keyInput = suggestion\n    this.key = suggestion\n    this.valueInput = \"\"\n    this.value = \"\"\n    this.fetchValuesForKey(suggestion)\n  }\n\n  /**\n   * Selects a value suggestion and updates the value field.\n   * @param suggestion - The selected value suggestion.\n   * @private\n   */\n  private selectValueSuggestion(suggestion: string) {\n    this.valueInput = suggestion\n    this.value = suggestion\n  }\n\n  /**\n   * Enables editing mode for the row.\n   * @private\n   */\n  private handleEdit() {\n    this.editable = true\n    this.tempValue = this.value\n  }\n\n  /**\n   * Saves the edited property and dispatches an update-row event.\n   * @private\n   */\n  private async handleSave() {\n    try {\n      const updatedProperty = await folksonomyApi.updateProductProperty(\n        this.productCode,\n        this.key,\n        this.tempValue,\n        this.version\n      )\n      this.editable = false\n\n      this.dispatchEvent(\n        new CustomEvent(\"update-row\", {\n          detail: {\n            key: updatedProperty.key,\n            value: updatedProperty.value,\n            version: updatedProperty.version,\n          },\n          bubbles: true,\n          composed: true,\n        })\n      )\n    } catch (error) {\n      console.error(\"Failed to update property\", error)\n    }\n  }\n\n  /**\n   * Cancels editing mode and restores the original value.\n   * @private\n   */\n  private handleCancel() {\n    this.editable = false\n    this.tempValue = this.value\n  }\n\n  /**\n   * Deletes the property and dispatches a delete-row event.\n   * @private\n   */\n  private async handleDelete() {\n    const deleteModal = document.createElement(\"delete-modal\")\n    deleteModal.addEventListener(\"confirm-delete\", async () => {\n      try {\n        await folksonomyApi.deleteProductProperty(this.productCode, this.key, this.version)\n        this.dispatchEvent(\n          new CustomEvent(\"delete-row\", {\n            detail: { key: this.key },\n            bubbles: true,\n            composed: true,\n          })\n        )\n      } catch (error) {\n        console.error(\"Failed to delete property\", error)\n      } finally {\n        deleteModal.remove()\n      }\n    })\n    document.body.appendChild(deleteModal)\n  }\n\n  /**\n   * Adds a custom key and value to the product properties.\n   * @private\n   */\n  private async addCustomKeyAndValue() {\n    if (this.keyInput && this.valueInput) {\n      try {\n        const newProperty = await folksonomyApi.addProductProperty(\n          this.productCode,\n          this.keyInput,\n          this.valueInput,\n          this.version\n        )\n        this.dispatchEvent(\n          new CustomEvent(\"add-row\", {\n            detail: { key: newProperty.key, value: newProperty.value },\n            bubbles: true,\n            composed: true,\n          })\n        )\n        this.keyInput = \"\"\n        this.valueInput = \"\"\n      } catch (error) {\n        console.error(\"Failed to add custom key and value\", error)\n      }\n    }\n  }\n\n  /**\n   * Handles input changes during editing.\n   * @param e - The input event.\n   * @private\n   */\n  private handleInputChange(e: Event) {\n    this.tempValue = (e.target as HTMLInputElement).value\n  }\n\n  /**\n   * Handles closing the new key modal.\n   * @private\n   */\n  private handleCloseNewKeyModal() {\n    this.showNewKeyModal = false\n  }\n\n  static override styles = [\n    FOLKSONOMY_INPUT,\n    ...getButtonClasses([ButtonType.Chocolate]),\n    css`\n      :host {\n        font-family: Arial, sans-serif;\n        font-size: 0.9rem;\n        color: #333;\n        width: 100%;\n        display: contents;\n      }\n\n      .odd-row {\n        background-color: #ffffff;\n      }\n\n      .even-row {\n        background-color: #f2f2f2;\n      }\n\n      .button-container {\n        display: flex;\n        gap: 0.5rem;\n        align-items: center;\n        width: 10rem;\n      }\n\n      .button-container button {\n        width: 10rem;\n      }\n\n      td {\n        padding: 0.5rem 1.2rem;\n        text-align: left;\n        border: none;\n      }\n      tr:not(.empty-row) td {\n        overflow: hidden;\n        text-overflow: ellipsis;\n        white-space: nowrap;\n      }\n\n      .property-link {\n        color: black;\n      }\n\n      #create-button {\n        width: 10rem;\n        padding: 0.4rem 0.8rem;\n      }\n\n      @media (max-width: 768px) {\n        .button-container {\n          flex-direction: column;\n        }\n\n        .button-container {\n          width: 7rem;\n        }\n\n        .button-container button {\n          font-size: 0.8rem;\n          padding: 0.4rem 0.8rem;\n          height: 2rem;\n          width: 7rem;\n        }\n\n        #create-button {\n          font-size: 0.8rem;\n          padding: 0.4rem 0.8rem;\n          height: 2rem;\n          width: 7rem;\n        }\n      }\n\n      @media (max-width: 480px) {\n        .button-container {\n          width: 5rem;\n        }\n\n        .button-container button {\n          width: 5rem;\n          font-size: 0.7rem;\n          padding: 0.3rem 0.5rem;\n          height: 1.6rem;\n        }\n\n        #create-button {\n          width: 5rem;\n          font-size: 0.7rem;\n          padding: 0.3rem 0.5rem;\n          height: 1.6rem;\n        }\n\n        td {\n          padding: 0.4rem 0.5rem;\n        }\n      }\n      autocomplete-input::part(autocomplete-input-list) {\n        position: relative !important;\n      }\n    `,\n  ]\n\n  override render() {\n    if (this.empty) {\n      return html`\n        <tr class=\"empty-row ${this.rowNumber % 2 === 0 ? \"even-row\" : \"odd-row\"}\">\n          <td>\n            <autocomplete-input\n              placeholder=${msg(\"New key\")}\n              .value=${this.keyInput}\n              .suggestions=${this.keySuggestions}\n              show-not-found-option\n              not-found-text=${msg(\"Not found? Create new key {value}\")}\n              @input-change=${(e: AutocompleteInputChangeEvent) => this.onKeyInput(e)}\n              @suggestion-select=${(e: AutocompleteSuggestionSelectEvent) =>\n                this.selectKeySuggestion(e.detail.value)}\n            ></autocomplete-input>\n          </td>\n          <td>\n            <autocomplete-input\n              placeholder=${msg(\"New value\")}\n              .value=${this.valueInput}\n              .suggestions=${this.valueSuggestions}\n              @input-change=${(e: AutocompleteInputChangeEvent) => this.onValueInput(e)}\n              @suggestion-select=${(e: AutocompleteSuggestionSelectEvent) =>\n                this.selectValueSuggestion(e.detail.value)}\n            ></autocomplete-input>\n          </td>\n          <td>\n            <div class=\"button-container\">\n              <button\n                class=\"button chocolate-button\"\n                @click=${this.addCustomKeyAndValue}\n                id=\"create-button\"\n              >\n                ${msg(\"Submit\")}\n              </button>\n            </div>\n          </td>\n        </tr>\n        ${this.showNewKeyModal\n          ? html`<new-key-modal @close-modal=${this.handleCloseNewKeyModal}></new-key-modal>`\n          : null}\n      `\n    }\n\n    return html`\n      <tr class=\"${this.rowNumber % 2 === 0 ? \"even-row\" : \"odd-row\"}\">\n        <td>\n          <a\n            class=\"property-link\"\n            href=\"https://wiki.openfoodfacts.org/Folksonomy/Property/${this.key}\"\n            >${this.key}</a\n          >\n        </td>\n        <td>\n          ${this.editable\n            ? html`<input\n                type=\"text\"\n                class=\"input\"\n                .value=${this.tempValue}\n                @input=${this.handleInputChange}\n              />`\n            : this.value}\n        </td>\n        ${this.pageType == \"edit\"\n          ? html`<td>\n              <div class=\"button-container\">\n                ${this.editable\n                  ? html`\n                      <button class=\"button chocolate-button\" @click=${this.handleSave}>\n                        ${msg(\"Save\")}\n                      </button>\n                      <button class=\"button chocolate-button\" @click=${this.handleCancel}>\n                        ${msg(\"Cancel\")}\n                      </button>\n                    `\n                  : html`<button class=\"button chocolate-button\" @click=${this.handleEdit}>\n                      ${msg(\"Edit\")}\n                    </button>`}\n                <button class=\"button chocolate-button\" @click=${this.handleDelete}>\n                  ${msg(\"Delete\")}\n                </button>\n              </div>\n            </td>`\n          : null}\n      </tr>\n      ${this.showNewKeyModal\n        ? html`<new-key-modal @close-modal=${this.handleCloseNewKeyModal}></new-key-modal>`\n        : null}\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"folksonomy-editor-row\": FolksonomyEditorRow\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { localized, msg } from \"@lit/localize\"\nimport \"./folksonomy-editor-row\"\nimport folksonomyApi from \"../../api/folksonomy\"\n\n/**\n * Folksonomy Editor\n * @element folksonomy-editor\n * This component allows users to add personalized properties and values to the Open Food Facts database. It is part of the Folksonomy Engine project.\n */\n@customElement(\"folksonomy-editor\")\n@localized()\nexport class FolksonomyEditor extends LitElement {\n  /**\n   * The product ID for which the properties are being added\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"product-code\" })\n  productCode = \"\"\n\n  /**\n   * The type of page being displayed (e.g., \"view\", \"edit\")\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"page-type\" })\n  pageType = \"view\"\n\n  /**\n   * The base URL for properties listing (e.g., \"https://world.openfoodfacts.org/properties\")\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"properties-base-url\" })\n  propertiesBaseUrl = \"/properties\"\n\n  /**\n   * The URL for properties documentation (e.g., \"https://wiki.openfoodfacts.org/Folksonomy/Property\")\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"properties-documentation-url\" })\n  propertiesDocumentationUrl = \"https://wiki.openfoodfacts.org/Folksonomy/Property\"\n\n  /**\n   * The URL for the Folksonomy Engine project (e.g., \"https://wiki.openfoodfacts.org/Folksonomy_Engine\")\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"folksonomy-engine-url\" })\n  folksonomyEngineUrl = \"https://wiki.openfoodfacts.org/Folksonomy_Engine\"\n\n  static override styles = css`\n    :host {\n      font-family: Arial, sans-serif;\n      color: #333;\n    }\n    .feus {\n      margin-bottom: 1rem;\n      background-color: #fff;\n      border: 1px solid #ddd;\n      border-radius: 8px;\n      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n      padding: 1rem;\n    }\n    .feus h2 {\n      font-size: 2.2rem;\n      font-weight: 600;\n      color: #222;\n      margin-top: 10px;\n      margin-bottom: 0.5rem;\n    }\n    .feus p {\n      font-size: 0.9rem;\n      line-height: 1.5;\n      margin-bottom: 0.8rem;\n    }\n    #free_properties_form table {\n      width: 100%;\n      border-collapse: collapse;\n      margin-top: 1rem;\n      border: solid 1px #ddd;\n      font-size: 0.9rem;\n      table-layout: fixed;\n    }\n    #free_properties_form table th,\n    #free_properties_form table td {\n      padding: 0.8rem;\n      text-align: left;\n      border: solid 1px #ddd;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;\n    }\n    #free_properties_form table th {\n      background-color: #dedede;\n      font-weight: bold;\n      cursor: pointer;\n      user-select: none;\n      white-space: nowrap;\n    }\n    .sort-header {\n      display: inline-flex;\n      align-items: center;\n      gap: 0.2em;\n    }\n    .sort-icon {\n      display: inline-flex;\n      flex-direction: column;\n      margin-left: 0.5em;\n      font-size: 0.9em;\n      line-height: 1;\n    }\n    .sort-arrow {\n      opacity: 0.3;\n      height: 0.8em;\n      width: 0.8em;\n      padding: 0;\n      margin: 0;\n      display: block;\n    }\n    .sort-arrow.active {\n      opacity: 1;\n    }\n    #free_properties_form table th.sortable {\n      padding-right: 0.8em;\n    }\n    #free_properties_form table th.sortable::before,\n    #free_properties_form table th.sortable::after {\n      display: none;\n    }\n    #free_properties_form table tr {\n      height: 4rem;\n    }\n    #free_properties_form table tr:nth-child(even) {\n      background-color: #f9f9f9;\n    }\n    @media (max-width: 480px) {\n      #free_properties_form table tr:first-child {\n        height: 0.5rem;\n      }\n    }\n  `\n\n  /**\n   * State representing all the properties and values\n   */\n  @state()\n  properties: Array<{ key: string; value: string; version: number }> = []\n\n  @state()\n  private sortColumn: \"key\" | \"value\" = \"key\"\n\n  @state()\n  private sortDirection: \"asc\" | \"desc\" = \"asc\"\n\n  private handleRowDelete(event: CustomEvent) {\n    const { key } = event.detail\n    this.properties = this.properties.filter((property) => property.key !== key)\n  }\n\n  private handleRowAdd(event: CustomEvent) {\n    const { key, value } = event.detail\n    if (key && value) {\n      this.properties = [...this.properties, { key, value, version: 1 }]\n      this.sortProperties()\n    } else {\n      console.error(\"Key or value is missing in the event detail.\")\n    }\n  }\n\n  private handleRowUpdate(event: CustomEvent) {\n    const { key, value, version } = event.detail\n    this.properties = this.properties.map((property) =>\n      property.key === key ? { ...property, value, version } : property\n    )\n    this.sortProperties()\n  }\n\n  private handleSort(column: \"key\" | \"value\") {\n    if (this.sortColumn === column) {\n      this.sortDirection = this.sortDirection === \"asc\" ? \"desc\" : \"asc\"\n    } else {\n      this.sortColumn = column\n      this.sortDirection = \"asc\"\n    }\n    this.sortProperties()\n  }\n\n  private sortProperties() {\n    const column = this.sortColumn\n    const direction = this.sortDirection === \"asc\" ? 1 : -1\n    this.properties = [...this.properties].sort((a, b) => {\n      // Use localeCompare for better, locale-aware sorting\n      const valueA = a[column]?.toString().toLowerCase() ?? \"\"\n      const valueB = b[column]?.toString().toLowerCase() ?? \"\"\n      return valueA.localeCompare(valueB, undefined, { numeric: true }) * direction\n    })\n  }\n\n  override connectedCallback() {\n    super.connectedCallback()\n    this.fetchAndLogFolksonomyKeys()\n\n    this.addEventListener(\"add-row\", this.handleRowAdd as EventListener)\n    this.addEventListener(\"update-row\", this.handleRowUpdate as EventListener)\n    this.addEventListener(\"delete-row\", this.handleRowDelete as EventListener)\n  }\n\n  override disconnectedCallback() {\n    super.disconnectedCallback()\n\n    this.removeEventListener(\"add-row\", this.handleRowAdd as EventListener)\n    this.removeEventListener(\"update-row\", this.handleRowUpdate as EventListener)\n    this.removeEventListener(\"delete-row\", this.handleRowDelete as EventListener)\n  }\n\n  private async fetchAndLogFolksonomyKeys() {\n    try {\n      const product_properties = await folksonomyApi.fetchProductProperties(this.productCode)\n\n      // update the state with the fetched properties\n      this.properties = product_properties.map((item: any) => ({\n        key: item.k,\n        value: item.v,\n        version: item.version,\n      }))\n      this.sortProperties()\n    } catch (error) {\n      console.error(\"Error fetching folksonomy keys:\", error)\n    }\n  }\n\n  private renderSortIcon(column: \"key\" | \"value\") {\n    const isActive = this.sortColumn === column\n    return html`\n      <span class=\"sort-icon\">\n        <svg\n          class=\"sort-arrow ${isActive && this.sortDirection === \"asc\" ? \"active\" : \"\"}\"\n          viewBox=\"0 0 10 6\"\n        >\n          <polygon points=\"5,0 10,6 0,6\" />\n        </svg>\n        <svg\n          class=\"sort-arrow ${isActive && this.sortDirection === \"desc\" ? \"active\" : \"\"}\"\n          viewBox=\"0 0 10 6\"\n          style=\"transform:rotate(180deg)\"\n        >\n          <polygon points=\"5,0 10,6 0,6\" />\n        </svg>\n      </span>\n    `\n  }\n\n  private renderForm() {\n    return html`\n      <form id=\"free_properties_form\">\n        <table>\n          <tr>\n            <th\n              @click=${() => this.handleSort(\"key\")}\n              class=${`sortable ${this.sortColumn === \"key\" ? `sort-${this.sortDirection}` : \"\"}`}\n            >\n              <span class=\"sort-header\"> ${msg(\"Property\")} ${this.renderSortIcon(\"key\")} </span>\n            </th>\n            <th\n              @click=${() => this.handleSort(\"value\")}\n              class=${`sortable ${this.sortColumn === \"value\" ? `sort-${this.sortDirection}` : \"\"}`}\n            >\n              <span class=\"sort-header\"> ${msg(\"Value\")} ${this.renderSortIcon(\"value\")} </span>\n            </th>\n            ${this.pageType == \"edit\" ? html`<th>${msg(\"Actions\")}</th>` : null}\n          </tr>\n          ${this.properties.map(\n            (item, index) =>\n              html`<folksonomy-editor-row\n                product-code=${this.productCode}\n                key=${item.key}\n                value=${item.value}\n                version=${item.version}\n                row-number=${index + 1}\n                page-type=${this.pageType}\n              ></folksonomy-editor-row>`\n          )}\n          ${this.pageType == \"edit\"\n            ? html`<folksonomy-editor-row\n                product-code=${this.productCode}\n                page-type=${this.pageType}\n                row-number=${this.properties.length + 1}\n                empty\n              ></folksonomy-editor-row>`\n            : null}\n        </table>\n      </form>\n    `\n  }\n\n  override render() {\n    return html`\n      <section>\n        <div class=\"feus\">\n          <div>\n            <div>\n              <h2>\n                ${msg(\"Personalized properties\")} (<span\n                  data-tooltip\n                  aria-haspopup=\"true\"\n                  data-position=\"top\"\n                  data-alignment=\"left\"\n                  title=${msg(\"Be aware the data model might be modified. Use at your own risk.\")}\n                  >beta</span\n                >)\n              </h2>\n              <p>\n                ${msg(\n                  html`These properties are created and filed by users for any kind of usages. Feel\n                    free to add your own. The properties and values you create\n                    <strong>must be factual</strong>. You can dive into\n                    <a href=\"${this.propertiesBaseUrl}\"\n                      >the list of properties already used by the community</a\n                    >\n                    or explore the\n                    <a href=\"${this.propertiesDocumentationUrl}\"\n                      >properties' documentation and its search engine</a\n                    >.`\n                )}\n              </p>\n              <p>${msg(\"Be aware the data model might be modified. Use at your own risk.\")}</p>\n              <p>\n                ${msg(\n                  html`This is brought by the\n                    <a href=\"${this.folksonomyEngineUrl}\">Folksonomy Engine project</a>. Don't\n                    hesitate to participate or give feedback`\n                )}\n              </p>\n              ${this.renderForm()}\n            </div>\n          </div>\n        </div>\n      </section>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"folksonomy-editor\": FolksonomyEditor\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\n\n/**\n * Dual Range Slider Component\n * @element dual-range-slider\n * A reusable component for selecting a range of values with two handles\n */\n@customElement(\"dual-range-slider\")\nexport class DualRangeSlider extends LitElement {\n  static override styles = css`\n    :host {\n      display: block;\n      width: 100%;\n    }\n\n    /* Range slider container */\n    .range-filter-container {\n      display: flex;\n      flex-direction: column;\n      gap: 0.5rem;\n      min-width: 200px;\n    }\n\n    .range-inputs {\n      display: flex;\n      gap: 0.25rem;\n      align-items: center;\n    }\n\n    .range-input {\n      width: 60px;\n      padding: 0.25rem;\n      border: 1px solid #ddd;\n      border-radius: 4px;\n      font-size: 0.75rem;\n      text-align: center;\n    }\n\n    .range-input:focus {\n      outline: none;\n      border-color: #341100;\n    }\n\n    .range-separator {\n      font-size: 0.75rem;\n      color: #666;\n    }\n\n    /* Custom range slider styles */\n    .range-slider {\n      width: 100%;\n      height: 6px;\n      border-radius: 3px;\n      background: #ddd;\n      outline: none;\n      opacity: 0.7;\n      transition: opacity 0.2s;\n      -webkit-appearance: none;\n      appearance: none;\n      position: relative;\n    }\n\n    .range-slider:hover {\n      opacity: 1;\n    }\n\n    .range-slider::-webkit-slider-thumb {\n      -webkit-appearance: none;\n      appearance: none;\n      width: 16px;\n      height: 16px;\n      border-radius: 50%;\n      background: #341100;\n      cursor: pointer;\n      box-shadow: 0px 0px 0px 3px rgba(52, 17, 0, 0.2);\n    }\n\n    .range-slider::-moz-range-thumb {\n      width: 16px;\n      height: 16px;\n      border-radius: 50%;\n      background: #341100;\n      cursor: pointer;\n      border: none;\n      box-shadow: 0px 0px 0px 3px rgba(52, 17, 0, 0.2);\n    }\n\n    .range-slider-container {\n      position: relative;\n      margin: 0.25rem 0;\n    }\n\n    .range-slider-track {\n      position: absolute;\n      height: 6px;\n      background: #341100;\n      border-radius: 3px;\n      top: 0;\n    }\n\n    .dual-range-container {\n      position: relative;\n      width: 100%;\n    }\n\n    .dual-range-slider {\n      position: relative;\n      height: 6px;\n      background: #ddd;\n      border-radius: 3px;\n      margin: 0.5rem 0;\n      width: 200px;\n      min-width: 180px;\n    }\n\n    .dual-range-slider input[type=\"range\"] {\n      position: absolute;\n      width: 100%;\n      height: 6px;\n      background: transparent;\n      -webkit-appearance: none;\n      appearance: none;\n      pointer-events: none;\n      outline: none;\n    }\n\n    .dual-range-slider input[type=\"range\"]::-webkit-slider-thumb {\n      -webkit-appearance: none;\n      appearance: none;\n      width: 16px;\n      height: 16px;\n      margin-top: -5px;\n      margin-left: -2px;\n      border-radius: 50%;\n      background: #341100;\n      cursor: pointer;\n      pointer-events: all;\n      box-shadow: 0px 0px 0px 3px rgba(52, 17, 0, 0.2);\n      border: none;\n    }\n\n    .dual-range-slider input[type=\"range\"]::-moz-range-thumb {\n      width: 16px;\n      height: 16px;\n      margin-top: -5px;\n      border-radius: 50%;\n      background: #341100;\n      cursor: pointer;\n      pointer-events: all;\n      box-shadow: 0px 0px 0px 3px rgba(52, 17, 0, 0.2);\n      border: none;\n    }\n\n    .dual-range-slider input[type=\"range\"]:first-child::-moz-range-thumb {\n      margin-left: -8px;\n    }\n\n    .dual-range-slider input[type=\"range\"]:last-child::-moz-range-thumb {\n      margin-right: -8px;\n    }\n\n    .dual-range-track {\n      position: absolute;\n      height: 6px;\n      background: #341100;\n      border-radius: 3px;\n      top: 0;\n    }\n\n    /* Mobile responsiveness */\n    @media (max-width: 768px) {\n      .range-filter-container {\n        min-width: 180px;\n      }\n\n      .range-input {\n        width: 50px;\n        font-size: 0.7rem;\n      }\n    }\n  `\n\n  @property({ type: Number })\n  min = 0\n\n  @property({ type: Number })\n  max = 100\n\n  @property({ type: Number })\n  minValue = 0\n\n  @property({ type: Number })\n  maxValue = 100\n\n  @property({ type: String })\n  type = \"range\"\n\n  private handleMinInput(value: string) {\n    const numValue = parseInt(value, 10)\n    if (isNaN(numValue)) return\n\n    // Ensure min doesn't go below absolute min or above current max\n    let newMinValue = Math.max(this.min, numValue)\n    newMinValue = Math.min(newMinValue, this.maxValue)\n\n    this.dispatchEvent(\n      new CustomEvent(\"range-change\", {\n        detail: {\n          type: this.type,\n          field: \"min\",\n          value: newMinValue,\n        },\n      })\n    )\n  }\n\n  private handleMaxInput(value: string) {\n    const numValue = parseInt(value, 10)\n    if (isNaN(numValue)) return\n\n    // Ensure max doesn't go above absolute max or below current min\n    let newMaxValue = Math.min(this.max, numValue)\n    newMaxValue = Math.max(newMaxValue, this.minValue)\n\n    this.dispatchEvent(\n      new CustomEvent(\"range-change\", {\n        detail: {\n          type: this.type,\n          field: \"max\",\n          value: newMaxValue,\n        },\n      })\n    )\n  }\n\n  override render() {\n    // If range is too small, show simple inputs instead\n    if (this.max - this.min < 2) {\n      return html`\n        <div class=\"range-filter-container\">\n          <div class=\"range-inputs\">\n            <input\n              type=\"number\"\n              class=\"range-input\"\n              .value=\"${this.minValue.toString()}\"\n              min=\"${this.min}\"\n              max=\"${this.maxValue}\"\n              @input=\"${(e: Event) => this.handleMinInput((e.target as HTMLInputElement).value)}\"\n            />\n            <span class=\"range-separator\">-</span>\n            <input\n              type=\"number\"\n              class=\"range-input\"\n              .value=\"${this.maxValue.toString()}\"\n              min=\"${this.minValue}\"\n              max=\"${this.max}\"\n              @input=\"${(e: Event) => this.handleMaxInput((e.target as HTMLInputElement).value)}\"\n            />\n          </div>\n        </div>\n      `\n    }\n\n    const percent1 = ((this.minValue - this.min) / (this.max - this.min)) * 100\n    const percent2 = ((this.maxValue - this.min) / (this.max - this.min)) * 100\n\n    return html`\n      <div class=\"range-filter-container\">\n        <div class=\"range-inputs\">\n          <input\n            type=\"number\"\n            class=\"range-input\"\n            .value=\"${this.minValue.toString()}\"\n            min=\"${this.min}\"\n            max=\"${this.maxValue}\"\n            @input=\"${(e: Event) => this.handleMinInput((e.target as HTMLInputElement).value)}\"\n          />\n          <span class=\"range-separator\">-</span>\n          <input\n            type=\"number\"\n            class=\"range-input\"\n            .value=\"${this.maxValue.toString()}\"\n            min=\"${this.minValue}\"\n            max=\"${this.max}\"\n            @input=\"${(e: Event) => this.handleMaxInput((e.target as HTMLInputElement).value)}\"\n          />\n        </div>\n        <div class=\"dual-range-container\">\n          <div class=\"dual-range-slider\">\n            <div\n              class=\"dual-range-track\"\n              style=\"left: ${percent1}%; width: ${percent2 - percent1}%\"\n            ></div>\n            <input\n              type=\"range\"\n              min=\"${this.min}\"\n              max=\"${this.max}\"\n              .value=\"${this.minValue.toString()}\"\n              @input=\"${(e: Event) => this.handleMinInput((e.target as HTMLInputElement).value)}\"\n            />\n            <input\n              type=\"range\"\n              min=\"${this.min}\"\n              max=\"${this.max}\"\n              .value=\"${this.maxValue.toString()}\"\n              @input=\"${(e: Event) => this.handleMaxInput((e.target as HTMLInputElement).value)}\"\n            />\n          </div>\n        </div>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"dual-range-slider\": DualRangeSlider\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { localized, msg, str } from \"@lit/localize\"\nimport { SignalWatcher } from \"@lit-labs/signals\"\nimport folksonomyApi from \"../../api/folksonomy\"\nimport { createDebounce, downloadCSV } from \"../../utils\"\nimport \"../shared/dual-range-slider\"\nimport type { PropertyClashCheck } from \"../../types/folksonomy\"\nimport { userInfo } from \"../../signals/folksonomy\"\n\n/**\n * Folksonomy Properties Viewer\n * @element folksonomy-properties\n * This component displays all contributed properties from the Folksonomy Engine project.\n */\n@customElement(\"folksonomy-properties\")\n@localized()\nexport class FolksonomyProperties extends SignalWatcher(LitElement) {\n  static override styles = css`\n    :host {\n      display: block;\n      font-family: Arial, sans-serif;\n      color: #333;\n    }\n\n    .properties-container {\n      margin-bottom: 1rem;\n      background-color: #fff;\n      border: 1px solid #ddd;\n      border-radius: 8px;\n      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n      padding: 1rem;\n    }\n\n    .properties-container h2 {\n      font-size: 2.2rem;\n      font-weight: 600;\n      color: #222;\n      margin-top: 10px;\n      margin-bottom: 0.5rem;\n    }\n\n    .properties-container p {\n      font-size: 0.9rem;\n      line-height: 1.5;\n      margin-bottom: 1rem;\n      color: #222;\n    }\n\n    .properties-container a {\n      color: #341100;\n    }\n\n    .properties-table {\n      width: 100%;\n      border-collapse: collapse;\n      margin-top: 1rem;\n      border: solid 1px #ddd;\n      font-size: 0.9rem;\n    }\n\n    .properties-table th,\n    .properties-table td {\n      padding: 0.8rem;\n      text-align: left;\n      border: solid 1px #ddd;\n    }\n\n    .properties-table th {\n      background-color: #f8f9fa;\n      font-weight: bold;\n      position: sticky;\n      top: 0;\n      z-index: 1;\n    }\n\n    .properties-table tr:nth-child(even) {\n      background-color: #f9f9f9;\n    }\n\n    .properties-table tr:hover {\n      background-color: #e8f4fd;\n    }\n\n    .property-name {\n      font-weight: 500;\n      color: #341100;\n    }\n\n    .doc-link {\n      font-size: 1.1rem;\n    }\n\n    .doc-link:hover {\n      opacity: 0.7;\n    }\n\n    .count {\n      text-align: right;\n      font-weight: 500;\n    }\n\n    .values {\n      text-align: right;\n      font-weight: 500;\n    }\n\n    .loading {\n      text-align: center;\n      padding: 2rem;\n      color: #666;\n    }\n\n    .error {\n      color: #dc3545;\n      text-align: center;\n      padding: 1rem;\n      background-color: #f8d7da;\n      border: 1px solid #f5c6cb;\n      border-radius: 4px;\n      margin: 1rem 0;\n    }\n\n    .empty-state {\n      text-align: center;\n      padding: 2rem;\n      color: #666;\n    }\n\n    /* Prepare table for filtering */\n    .filter-row {\n      background-color: #f8f9fa;\n    }\n\n    .filter-input {\n      width: 100%;\n      padding: 0.25rem;\n      border: 1px solid #ddd;\n      border-radius: 4px;\n      font-size: 0.875rem;\n      box-sizing: border-box;\n    }\n\n    .filter-input:focus {\n      outline: none;\n      border-color: #007bff;\n      box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);\n    }\n\n    .filter-controls {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      margin: 1rem 0;\n      padding: 0.5rem;\n      background-color: #f8f9fa;\n      border-radius: 4px;\n    }\n\n    .rows-counter {\n      font-size: 0.875rem;\n      color: #666;\n    }\n\n    .reset-btn {\n      background-color: #341100;\n      color: white;\n      border: 1px solid #341100;\n      padding: 0.4rem 0.8rem;\n      border-radius: 4px;\n      cursor: pointer;\n      transition:\n        background-color 0.3s,\n        color 0.3s;\n      margin-left: 1rem;\n    }\n\n    .download-btn {\n      background-color: #341100;\n      color: white;\n      border: 1px solid #341100;\n      padding: 0.4rem 0.8rem;\n      border-radius: 4px;\n      cursor: pointer;\n      transition:\n        background-color 0.3s,\n        color 0.3s;\n    }\n\n    .button-group {\n      display: flex;\n      gap: 0.5rem;\n    }\n\n    .status-bar {\n      font-size: 0.875rem;\n      color: #666;\n      font-style: italic;\n    }\n\n    .actions-column {\n      text-align: center;\n      width: 120px;\n    }\n\n    .actions-buttons {\n      display: flex;\n      gap: 0.25rem;\n      justify-content: center;\n      flex-wrap: wrap;\n    }\n\n    .action-btn {\n      background-color: transparent;\n      border: 1px solid #341100;\n      color: #341100;\n      padding: 0.25rem 0.5rem;\n      border-radius: 3px;\n      cursor: pointer;\n      font-size: 0.75rem;\n      transition: all 0.2s;\n      min-width: 50px;\n    }\n\n    .action-btn:hover {\n      background-color: #341100;\n      color: white;\n    }\n\n    .action-btn.delete {\n      border-color: #dc3545;\n      color: #dc3545;\n    }\n\n    .action-btn.delete:hover {\n      background-color: #dc3545;\n      color: white;\n    }\n\n    .action-btn:disabled {\n      opacity: 0.5;\n      cursor: not-allowed;\n    }\n\n    .action-btn:disabled:hover {\n      background-color: transparent;\n      color: #341100;\n    }\n\n    .action-btn.delete:disabled:hover {\n      background-color: transparent;\n      color: #dc3545;\n    }\n\n    /* Modal styles */\n    .modal-overlay {\n      position: fixed;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      background-color: rgba(0, 0, 0, 0.5);\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      z-index: 1000;\n      animation: fadeIn 0.2s ease-out;\n    }\n\n    .modal {\n      background: white;\n      border-radius: 8px;\n      box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);\n      max-width: 500px;\n      width: 90%;\n      max-height: 90vh;\n      overflow-y: auto;\n      animation: slideIn 0.2s ease-out;\n    }\n\n    .modal-header {\n      padding: 1.5rem 1.5rem 0;\n      border-bottom: 1px solid #eee;\n    }\n\n    .modal-title {\n      font-size: 1.25rem;\n      font-weight: 600;\n      color: #333;\n      margin: 0 0 1rem 0;\n    }\n\n    .modal-body {\n      padding: 1.5rem;\n    }\n\n    .modal-footer {\n      padding: 0 1.5rem 1.5rem;\n      display: flex;\n      gap: 0.75rem;\n      justify-content: flex-end;\n    }\n\n    .modal-input {\n      width: 100%;\n      padding: 0.75rem;\n      border: 1px solid #ddd;\n      border-radius: 4px;\n      font-size: 1rem;\n      margin-top: 0.5rem;\n    }\n\n    .modal-input:focus {\n      outline: none;\n      border-color: #341100;\n      box-shadow: 0 0 0 2px rgba(52, 17, 0, 0.1);\n    }\n\n    .modal-text {\n      color: #555;\n      line-height: 1.5;\n      margin-bottom: 1rem;\n    }\n\n    .modal-btn {\n      padding: 0.75rem 1.5rem;\n      border: none;\n      border-radius: 4px;\n      font-size: 0.9rem;\n      font-weight: 500;\n      cursor: pointer;\n      transition: all 0.2s;\n      min-width: 80px;\n    }\n\n    .modal-btn-primary {\n      background-color: #341100;\n      color: white;\n    }\n\n    .modal-btn-primary:hover {\n      background-color: #2a0e00;\n    }\n\n    .modal-btn-danger {\n      background-color: #dc3545;\n      color: white;\n    }\n\n    .modal-btn-danger:hover {\n      background-color: #c82333;\n    }\n\n    .modal-btn-secondary {\n      background-color: #f8f9fa;\n      color: #333;\n      border: 1px solid #ddd;\n    }\n\n    .modal-btn-secondary:hover {\n      background-color: #e9ecef;\n    }\n\n    .modal-btn:disabled {\n      opacity: 0.5;\n      cursor: not-allowed;\n    }\n\n    .clash-info {\n      background-color: #fff3cd;\n      border: 1px solid #ffeaa7;\n      border-radius: 4px;\n      padding: 1rem;\n      margin: 1rem 0;\n    }\n\n    .clash-stat {\n      display: flex;\n      justify-content: space-between;\n      margin: 0.5rem 0;\n    }\n\n    .clash-stat-label {\n      font-weight: 500;\n    }\n\n    .clash-stat-value {\n      font-weight: bold;\n      color: #856404;\n    }\n\n    @keyframes fadeIn {\n      from {\n        opacity: 0;\n      }\n      to {\n        opacity: 1;\n      }\n    }\n\n    @keyframes slideIn {\n      from {\n        opacity: 0;\n        transform: translateY(-20px);\n      }\n      to {\n        opacity: 1;\n        transform: translateY(0);\n      }\n    }\n\n    /* Mobile responsiveness */\n    @media (max-width: 768px) {\n      .properties-table {\n        font-size: 0.8rem;\n      }\n\n      .properties-table th,\n      .properties-table td {\n        padding: 0.5rem;\n      }\n\n      .properties-container h2 {\n        font-size: 1.8rem;\n      }\n\n      .properties-container p {\n        font-size: 0.8rem;\n      }\n\n      .actions-column {\n        width: 100px;\n      }\n\n      .actions-buttons {\n        flex-direction: column;\n        gap: 0.125rem;\n      }\n\n      .action-btn {\n        font-size: 0.7rem;\n        padding: 0.2rem 0.4rem;\n        min-width: 40px;\n      }\n\n      .modal {\n        width: 95%;\n        margin: 1rem;\n      }\n\n      .modal-footer {\n        flex-direction: column;\n      }\n\n      .modal-btn {\n        width: 100%;\n      }\n    }\n  `\n\n  /**\n   * Path to single property, the property name is appended to the end.\n   * It can be a full URL, a relative or absolute path\n   */\n  @property({ attribute: \"property-base-path\" })\n  propertyBasePath = \"/property/\"\n\n  @state()\n  private properties: Array<{ k: string; count: number; values: number }> = []\n\n  @state()\n  private filteredProperties: Array<{ k: string; count: number; values: number }> = []\n\n  @state()\n  private loading = false\n\n  @state()\n  private error: string | null = null\n\n  @state()\n  private filters = {\n    property: \"\",\n    countMin: 0,\n    countMax: 0,\n    valuesMin: 0,\n    valuesMax: 0,\n  }\n\n  @state()\n  private ranges = {\n    countMin: 0,\n    countMax: 0,\n    valuesMin: 0,\n    valuesMax: 0,\n  }\n\n  @state()\n  private showRenameModal = false\n\n  @state()\n  private showDeleteModal = false\n\n  @state()\n  private showClashModal = false\n\n  @state()\n  private showMessageModal = false\n\n  @state()\n  private renameModalData = {\n    property: \"\",\n    newProperty: \"\",\n  }\n\n  @state()\n  private deleteModalProperty = \"\"\n\n  @state()\n  private clashData: PropertyClashCheck | null = null\n\n  @state()\n  private messageModalData = {\n    title: \"\",\n    message: \"\",\n    type: \"success\" as \"success\" | \"error\",\n  }\n\n  private filterDebounce = createDebounce(1100)\n\n  override async connectedCallback() {\n    super.connectedCallback()\n    await this.fetchProperties()\n    await folksonomyApi.fetchUserInfo()\n  }\n\n  override disconnectedCallback() {\n    super.disconnectedCallback()\n    // Clean up filter debounce\n    this.filterDebounce.clear()\n  }\n\n  private async fetchProperties() {\n    this.loading = true\n    this.error = null\n\n    try {\n      const data = await folksonomyApi.fetchKeys()\n\n      // Sort by count (descending order)\n      this.properties = data.sort((a, b) => a.k.localeCompare(b.k))\n      this.filteredProperties = [...this.properties]\n\n      // Calculate min/max ranges for sliders\n      if (this.properties.length > 0) {\n        const counts = this.properties.map((p) => p.count)\n        const values = this.properties.map((p) => p.values)\n\n        const countMin = Math.min(...counts)\n        const countMax = Math.max(...counts)\n        const valuesMin = Math.min(...values)\n        const valuesMax = Math.max(...values)\n\n        // Ensure minimum range of 1 to prevent overlapping handles\n        this.ranges = {\n          countMin: countMin,\n          countMax: Math.max(countMax, countMin + 1),\n          valuesMin: valuesMin,\n          valuesMax: Math.max(valuesMax, valuesMin + 1),\n        }\n\n        // Initialize filters with full range\n        this.filters = {\n          property: \"\",\n          countMin: this.ranges.countMin,\n          countMax: this.ranges.countMax,\n          valuesMin: this.ranges.valuesMin,\n          valuesMax: this.ranges.valuesMax,\n        }\n      }\n    } catch (error) {\n      console.error(\"Error fetching folksonomy properties:\", error)\n      this.error = \"error\"\n    } finally {\n      this.loading = false\n    }\n  }\n\n  private get canModerateProperties(): boolean {\n    const currentUserInfo = userInfo.get()\n    return currentUserInfo?.admin === true || currentUserInfo?.moderator === true\n  }\n\n  private getPropertyUrl(propertyName: string) {\n    return `${this.propertyBasePath}${propertyName}`\n  }\n\n  private getDocumentationUrl(propertyName: string) {\n    return `https://wiki.openfoodfacts.org/Folksonomy/Property/${propertyName}`\n  }\n\n  private applyFilters() {\n    const { property, countMin, countMax, valuesMin, valuesMax } = this.filters\n\n    this.filteredProperties = this.properties.filter((item) => {\n      const matchesProperty = !property || item.k.toLowerCase().includes(property.toLowerCase())\n      const matchesCount = item.count >= countMin && item.count <= countMax\n      const matchesValues = item.values >= valuesMin && item.values <= valuesMax\n\n      return matchesProperty && matchesCount && matchesValues\n    })\n  }\n\n  private handleFilterInput(field: \"property\", value: string) {\n    this.filters = {\n      ...this.filters,\n      [field]: value,\n    }\n\n    // Debounce filtering with 1100ms delay (as specified in original config)\n    this.filterDebounce.debounce(() => {\n      this.applyFilters()\n    })\n  }\n\n  private handleRangeChange(event: CustomEvent) {\n    const { type, field, value } = event.detail\n\n    let filterField: keyof typeof this.filters\n    if (type === \"count\") {\n      filterField = field === \"min\" ? \"countMin\" : \"countMax\"\n    } else {\n      filterField = field === \"min\" ? \"valuesMin\" : \"valuesMax\"\n    }\n\n    this.filters = {\n      ...this.filters,\n      [filterField]: value,\n    }\n\n    // Immediate filtering for range inputs\n    this.applyFilters()\n  }\n\n  private resetFilters() {\n    this.filters = {\n      property: \"\",\n      countMin: this.ranges.countMin,\n      countMax: this.ranges.countMax,\n      valuesMin: this.ranges.valuesMin,\n      valuesMax: this.ranges.valuesMax,\n    }\n    this.filteredProperties = [...this.properties]\n  }\n\n  private handleDownloadCSV() {\n    const headers = [msg(\"Property\"), msg(\"Count\"), msg(\"Values\")]\n    const rows = this.filteredProperties.map((item) => [item.k, item.count, item.values])\n    const today = new Date().toISOString().split(\"T\")[0]\n    const filename = `folksonomy_properties_${today}.csv`\n\n    downloadCSV(rows, filename, headers)\n  }\n\n  // Property moderation methods\n  private openRenameModal(property: string) {\n    this.renameModalData = {\n      property,\n      newProperty: \"\",\n    }\n    this.showRenameModal = true\n  }\n\n  private closeRenameModal() {\n    this.showRenameModal = false\n    this.renameModalData = {\n      property: \"\",\n      newProperty: \"\",\n    }\n  }\n\n  private openDeleteModal(property: string) {\n    this.deleteModalProperty = property\n    this.showDeleteModal = true\n  }\n\n  private closeDeleteModal() {\n    this.showDeleteModal = false\n    this.deleteModalProperty = \"\"\n  }\n\n  private closeClashModal() {\n    this.showClashModal = false\n    this.clashData = null\n    // Clear rename data when clash modal is closed (canceled)\n    this.renameModalData = {\n      property: \"\",\n      newProperty: \"\",\n    }\n  }\n\n  private showMessage(type: \"success\" | \"error\", title: string, message: string) {\n    this.messageModalData = { type, title, message }\n    this.showMessageModal = true\n  }\n\n  private closeMessageModal() {\n    this.showMessageModal = false\n    this.messageModalData = {\n      title: \"\",\n      message: \"\",\n      type: \"success\",\n    }\n  }\n\n  private async handleCheckClash() {\n    const { property, newProperty } = this.renameModalData\n\n    if (!newProperty.trim() || newProperty.trim() === property) {\n      return\n    }\n\n    try {\n      const clashData = await folksonomyApi.checkPropertyClash({\n        old_property: property,\n        new_property: newProperty.trim(),\n      })\n\n      this.clashData = clashData\n      // Don't clear the rename data yet - we need it for the actual rename\n      this.showRenameModal = false\n      this.showClashModal = true\n    } catch (error) {\n      console.error(\"Error checking property clash:\", error)\n      this.showMessage(\n        \"error\",\n        msg(\"Error\"),\n        msg(\"Failed to check property conflicts. Please try again.\")\n      )\n    }\n  }\n\n  private async handleRenameProperty() {\n    const { property, newProperty } = this.renameModalData\n\n    try {\n      await folksonomyApi.renameProperty({\n        old_property: property,\n        new_property: newProperty.trim(),\n      })\n\n      // Clear all modal states after successful rename\n      this.showClashModal = false\n      this.clashData = null\n      this.renameModalData = {\n        property: \"\",\n        newProperty: \"\",\n      }\n\n      await this.fetchProperties()\n      this.showMessage(\"success\", msg(\"Success\"), msg(\"Property renamed successfully!\"))\n    } catch (error) {\n      console.error(\"Error renaming property:\", error)\n      this.showMessage(\"error\", msg(\"Error\"), msg(\"Failed to rename property. Please try again.\"))\n    }\n  }\n\n  private async handleDeleteProperty() {\n    try {\n      await folksonomyApi.deleteProperty({\n        property: this.deleteModalProperty,\n      })\n\n      this.closeDeleteModal()\n      await this.fetchProperties()\n      this.showMessage(\"success\", msg(\"Success\"), msg(\"Property deleted successfully!\"))\n    } catch (error) {\n      console.error(\"Error deleting property:\", error)\n      this.showMessage(\"error\", msg(\"Error\"), msg(\"Failed to delete property. Please try again.\"))\n    }\n  }\n\n  private renderPropertyActions(property: { k: string; count: number; values: number }) {\n    return html`\n      <td class=\"actions-column\">\n        <div class=\"actions-buttons\">\n          <button\n            class=\"action-btn\"\n            @click=\"${() => this.openRenameModal(property.k)}\"\n            title=\"${msg(\"Rename this property\")}\"\n          >\n            ${msg(\"Rename\")}\n          </button>\n          <button\n            class=\"action-btn delete\"\n            @click=\"${() => this.openDeleteModal(property.k)}\"\n            title=\"${msg(\"Delete this property\")}\"\n          >\n            ${msg(\"Delete\")}\n          </button>\n        </div>\n      </td>\n    `\n  }\n\n  private renderRenameModal() {\n    if (!this.showRenameModal) return \"\"\n\n    return html`\n      <div class=\"modal-overlay\" @click=\"${this.closeRenameModal}\">\n        <div class=\"modal\" @click=\"${(e: Event) => e.stopPropagation()}\">\n          <div class=\"modal-header\">\n            <h3 class=\"modal-title\">${msg(\"Rename Property\")}</h3>\n          </div>\n          <div class=\"modal-body\">\n            <div class=\"modal-text\">\n              ${msg(str`Rename property '${this.renameModalData.property}' to:`)}\n            </div>\n            <label for=\"new-property\">${msg(\"New property name:\")}</label>\n            <input\n              id=\"new-property\"\n              type=\"text\"\n              class=\"modal-input\"\n              .value=\"${this.renameModalData.newProperty}\"\n              @input=\"${(e: Event) => {\n                this.renameModalData = {\n                  ...this.renameModalData,\n                  newProperty: (e.target as HTMLInputElement).value,\n                }\n              }}\"\n              @keydown=\"${(e: KeyboardEvent) => {\n                if (e.key === \"Enter\") {\n                  this.handleCheckClash()\n                } else if (e.key === \"Escape\") {\n                  this.closeRenameModal()\n                }\n              }}\"\n              placeholder=\"${msg(\"Enter new property name...\")}\"\n              autofocus\n            />\n          </div>\n          <div class=\"modal-footer\">\n            <button class=\"modal-btn modal-btn-secondary\" @click=\"${this.closeRenameModal}\">\n              ${msg(\"Cancel\")}\n            </button>\n            <button\n              class=\"modal-btn modal-btn-primary\"\n              @click=\"${this.handleCheckClash}\"\n              ?disabled=\"${!this.renameModalData.newProperty.trim() ||\n              this.renameModalData.newProperty.trim() === this.renameModalData.property}\"\n            >\n              ${msg(\"Check Conflicts\")}\n            </button>\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  private renderClashModal() {\n    if (!this.showClashModal || !this.clashData) return \"\"\n\n    return html`\n      <div class=\"modal-overlay\" @click=\"${this.closeClashModal}\">\n        <div class=\"modal\" @click=\"${(e: Event) => e.stopPropagation()}\">\n          <div class=\"modal-header\">\n            <h3 class=\"modal-title\">${msg(\"Property Rename Conflicts\")}</h3>\n          </div>\n          <div class=\"modal-body\">\n            <div class=\"modal-text\">\n              ${msg(\n                str`Renaming '${this.renameModalData.property}' to '${this.renameModalData.newProperty}' will affect:`\n              )}\n            </div>\n            <div class=\"clash-info\">\n              <div class=\"clash-stat\">\n                <span class=\"clash-stat-label\">${msg(\"Products with both properties:\")}</span>\n                <span class=\"clash-stat-value\">${this.clashData.products_with_both}</span>\n              </div>\n              <div class=\"clash-stat\">\n                <span class=\"clash-stat-label\">${msg(\"Products with old property only:\")}</span>\n                <span class=\"clash-stat-value\">${this.clashData.products_with_old_only}</span>\n              </div>\n              <div class=\"clash-stat\">\n                <span class=\"clash-stat-label\">${msg(\"Products with new property only:\")}</span>\n                <span class=\"clash-stat-value\">${this.clashData.products_with_new_only}</span>\n              </div>\n            </div>\n            <div class=\"modal-text\">\n              <strong>${msg(\"Do you want to proceed with the rename?\")}</strong>\n            </div>\n          </div>\n          <div class=\"modal-footer\">\n            <button class=\"modal-btn modal-btn-secondary\" @click=\"${this.closeClashModal}\">\n              ${msg(\"Cancel\")}\n            </button>\n            <button class=\"modal-btn modal-btn-danger\" @click=\"${this.handleRenameProperty}\">\n              ${msg(\"Proceed with Rename\")}\n            </button>\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  private renderDeleteModal() {\n    if (!this.showDeleteModal) return \"\"\n\n    return html`\n      <div class=\"modal-overlay\" @click=\"${this.closeDeleteModal}\">\n        <div class=\"modal\" @click=\"${(e: Event) => e.stopPropagation()}\">\n          <div class=\"modal-header\">\n            <h3 class=\"modal-title\">${msg(\"Delete Property\")}</h3>\n          </div>\n          <div class=\"modal-body\">\n            <div class=\"modal-text\">\n              ${msg(\n                str`Are you sure you want to delete the property '${this.deleteModalProperty}'?`\n              )}\n            </div>\n            <div class=\"modal-text\">\n              <strong>${msg(\"This action cannot be undone.\")}</strong>\n            </div>\n          </div>\n          <div class=\"modal-footer\">\n            <button class=\"modal-btn modal-btn-secondary\" @click=\"${this.closeDeleteModal}\">\n              ${msg(\"Cancel\")}\n            </button>\n            <button class=\"modal-btn modal-btn-danger\" @click=\"${this.handleDeleteProperty}\">\n              ${msg(\"Delete\")}\n            </button>\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  private renderMessageModal() {\n    if (!this.showMessageModal) return \"\"\n\n    return html`\n      <div class=\"modal-overlay\" @click=\"${this.closeMessageModal}\">\n        <div class=\"modal\" @click=\"${(e: Event) => e.stopPropagation()}\">\n          <div class=\"modal-header\">\n            <h3 class=\"modal-title\">${this.messageModalData.title}</h3>\n          </div>\n          <div class=\"modal-body\">\n            <div class=\"modal-text\">${this.messageModalData.message}</div>\n          </div>\n          <div class=\"modal-footer\">\n            <button class=\"modal-btn modal-btn-primary\" @click=\"${this.closeMessageModal}\">\n              ${msg(\"OK\")}\n            </button>\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  private renderTableHeader() {\n    return html`\n      <thead>\n        <tr>\n          <th></th>\n          <th class=\"property-name-header\">${msg(\"Property\")}</th>\n          <th class=\"doc\">${msg(\"Documentation\")}</th>\n          <th class=\"count\">${msg(\"Count\")}</th>\n          <th class=\"values\">${msg(\"Values\")}</th>\n          ${this.canModerateProperties\n            ? html`<th class=\"actions-column\">${msg(\"Actions\")}</th>`\n            : \"\"}\n        </tr>\n        <tr class=\"filter-row\">\n          <td></td>\n          <td>\n            <input\n              type=\"text\"\n              class=\"filter-input\"\n              placeholder=\"${msg(\"Filter properties...\")}\"\n              .value=\"${this.filters.property}\"\n              @input=\"${(e: Event) =>\n                this.handleFilterInput(\"property\", (e.target as HTMLInputElement).value)}\"\n            />\n          </td>\n          <td></td>\n          <td>\n            <dual-range-slider\n              type=\"count\"\n              min=\"${this.ranges.countMin}\"\n              max=\"${this.ranges.countMax}\"\n              minValue=\"${this.filters.countMin}\"\n              maxValue=\"${this.filters.countMax}\"\n              @range-change=\"${this.handleRangeChange}\"\n            ></dual-range-slider>\n          </td>\n          <td>\n            <dual-range-slider\n              type=\"values\"\n              min=\"${this.ranges.valuesMin}\"\n              max=\"${this.ranges.valuesMax}\"\n              minValue=\"${this.filters.valuesMin}\"\n              maxValue=\"${this.filters.valuesMax}\"\n              @range-change=\"${this.handleRangeChange}\"\n            ></dual-range-slider>\n          </td>\n          ${this.canModerateProperties ? html`<td></td>` : \"\"}\n        </tr>\n      </thead>\n    `\n  }\n\n  private renderPropertyRow(property: { k: string; count: number; values: number }) {\n    return html`\n      <tr class=\"property\">\n        <td></td>\n        <td>\n          <a href=\"${this.getPropertyUrl(property.k)}\" class=\"property-name\"> ${property.k} </a>\n        </td>\n        <td>\n          <a\n            href=\"${this.getDocumentationUrl(property.k)}\"\n            class=\"doc-link\"\n            title=\"${msg(str`Documentation for ${property.k}`)}\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            🛈\n          </a>\n        </td>\n        <td class=\"count\">${property.count}</td>\n        <td class=\"values\">${property.values}</td>\n        ${this.canModerateProperties ? this.renderPropertyActions(property) : \"\"}\n      </tr>\n    `\n  }\n\n  private renderContent() {\n    if (this.loading) {\n      return html`<div class=\"loading\">${msg(\"Loading properties...\")}</div>`\n    }\n\n    if (this.error) {\n      return html`<div class=\"error\">\n        ${msg(\"Failed to load properties. Please try again later.\")}\n      </div>`\n    }\n\n    if (this.properties.length === 0) {\n      return html` <div class=\"empty-state\">${msg(\"No properties found.\")}</div> `\n    }\n\n    return html`\n      <div class=\"filter-controls\">\n        <div class=\"rows-counter\">\n          ${msg(\"Rows\")}: ${this.filteredProperties.length} / ${this.properties.length}\n        </div>\n        <div class=\"button-group\">\n          <button class=\"download-btn\" @click=\"${this.handleDownloadCSV}\">\n            ${msg(\"Download CSV\")}\n          </button>\n          <button class=\"reset-btn\" @click=\"${this.resetFilters}\">${msg(\"Reset\")}</button>\n        </div>\n      </div>\n      <table class=\"properties-table\" id=\"folksonomy-properties-table\">\n        ${this.renderTableHeader()}\n        <tbody id=\"free_prop_body\">\n          ${this.filteredProperties.map((property) => this.renderPropertyRow(property))}\n        </tbody>\n      </table>\n    `\n  }\n\n  override render() {\n    return html`\n      <div class=\"properties-container\">\n        <slot name=\"properties-introduction\">\n          <h2 id=\"property_title\">${msg(\"Folksonomy Properties\")}</h2>\n          <p>\n            ${msg(\n              \"Explore all contributed properties from the Folksonomy Engine project. These properties provide additional metadata and insights about products in the Open Food Facts database.\"\n            )}\n          </p>\n        </slot>\n        ${this.renderContent()}\n      </div>\n\n      ${this.renderRenameModal()} ${this.renderClashModal()} ${this.renderDeleteModal()}\n      ${this.renderMessageModal()}\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"folksonomy-properties\": FolksonomyProperties\n  }\n}\n","import { LitElement, html, css } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { downloadCSV } from \"../../utils\"\nimport { localized, msg, str } from \"@lit/localize\"\nimport { SignalWatcher } from \"@lit-labs/signals\"\nimport folksonomyApi from \"../../api/folksonomy\"\nimport { userInfo } from \"../../signals/folksonomy\"\n\n/**\n * Folksonomy Property Products Viewer\n * @element folksonomy-property-products\n * This component displays products that use a specific folksonomy property.\n * Note: The propertyName attribute is initialized once and cannot be modified dynamically, to change it, the component must be reinitialized.\n */\n@customElement(\"folksonomy-property-products\")\n@localized()\nexport class FolksonomyPropertyProducts extends SignalWatcher(LitElement) {\n  static override styles = css`\n    :host {\n      font-family: Arial, sans-serif;\n      color: #333;\n    }\n\n    .property-container {\n      margin: 0 auto 1rem auto;\n      background-color: #fff;\n      border: 1px solid #ddd;\n      border-radius: 8px;\n      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n      padding: 1rem;\n      box-sizing: border-box;\n    }\n\n    .property-container h2 {\n      font-size: 2.2rem;\n      font-weight: 400;\n      color: #222;\n      margin-top: 10px;\n      margin-bottom: 0.5rem;\n    }\n\n    .property-container p {\n      font-size: 0.9rem;\n      line-height: 1.5;\n      margin-bottom: 1rem;\n      color: #222;\n    }\n\n    .property-container a {\n      color: #341100;\n    }\n\n    .content-wrapper {\n      display: flex;\n      gap: 1rem;\n      align-items: flex-start;\n    }\n\n    .main-content {\n      flex: 1;\n      min-width: 0;\n    }\n\n    .header-section {\n      display: flex;\n      justify-content: space-between;\n      align-items: flex-start;\n      margin-bottom: 1rem;\n    }\n\n    .property-title-container {\n      flex: 1;\n      min-width: 0;\n    }\n\n    .info-box {\n      margin-top: 10px;\n      align-self: flex-start;\n    }\n\n    .table-container {\n      width: 100%;\n      max-width: 1200px;\n      margin: 0 auto;\n    }\n\n    .products-table {\n      width: 100%;\n      border-collapse: collapse;\n      margin-top: 1rem;\n      border: solid 1px #ddd;\n      font-size: 0.9rem;\n    }\n\n    .products-table th,\n    .products-table td {\n      padding: 0.8rem;\n      text-align: left;\n      border: solid 1px #ddd;\n    }\n\n    .products-table th {\n      background-color: #f8f9fa;\n      font-weight: bold;\n      position: sticky;\n      top: 0;\n      z-index: 1;\n    }\n\n    .products-table tr:nth-child(even) {\n      background-color: #f9f9f9;\n    }\n\n    .products-table tr:hover {\n      background-color: #e8f4fd;\n    }\n\n    .product-code {\n      font-weight: 500;\n      color: #341100;\n    }\n\n    .property-value {\n      font-weight: 500;\n      color: #341100;\n    }\n\n    .count {\n      text-align: right;\n      font-weight: bold;\n      color: #333;\n    }\n\n    .count-header {\n      text-align: right;\n    }\n\n    .loading {\n      text-align: center;\n      padding: 2rem;\n      color: #666;\n    }\n\n    .error {\n      color: #dc3545;\n      text-align: center;\n      padding: 1rem;\n      background-color: #f8d7da;\n      border: 1px solid #f5c6cb;\n      border-radius: 4px;\n      margin: 1rem 0;\n    }\n\n    .empty-state {\n      text-align: center;\n      padding: 2rem;\n      color: #666;\n    }\n\n    /* Filter styles */\n    .filter-row {\n      background-color: #f8f9fa;\n    }\n\n    .filter-input {\n      width: 100%;\n      padding: 0.25rem;\n      border: 1px solid #ddd;\n      border-radius: 4px;\n      font-size: 0.875rem;\n      box-sizing: border-box;\n    }\n\n    .filter-input:focus {\n      outline: none;\n      border-color: #007bff;\n      box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);\n    }\n\n    .filter-controls {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      margin: 1rem 0;\n      padding: 0.5rem;\n      background-color: #f8f9fa;\n      border-radius: 4px;\n    }\n\n    .rows-counter {\n      font-size: 0.875rem;\n      color: #666;\n    }\n\n    .download-btn {\n      background-color: #341100;\n      color: white;\n      border: 1px solid #341100;\n      padding: 0.4rem 0.8rem;\n      border-radius: 4px;\n      cursor: pointer;\n      transition:\n        background-color 0.3s,\n        color 0.3s;\n    }\n\n    .download-btn:hover {\n      background-color: rgb(255, 255, 255);\n      color: #341100;\n      border: 1px solid #341100;\n    }\n\n    .reset-btn {\n      background-color: #341100;\n      color: white;\n      border: 1px solid #341100;\n      padding: 0.4rem 0.8rem;\n      border-radius: 4px;\n      cursor: pointer;\n      transition:\n        background-color 0.3s,\n        color 0.3s;\n      margin-left: 1rem;\n    }\n\n    .reset-btn:hover {\n      background-color: rgb(255, 255, 255);\n      color: #341100;\n      border: 1px solid #341100;\n    }\n\n    .button-group {\n      display: flex;\n      gap: 0.5rem;\n    }\n\n    .view-mode-toggle {\n      display: flex;\n      background-color: #f8f9fa;\n      border: 1px solid #ddd;\n      border-radius: 4px;\n      overflow: hidden;\n    }\n\n    .view-mode-btn {\n      background-color: transparent;\n      border: none;\n      padding: 0.4rem 0.8rem;\n      cursor: pointer;\n      transition: background-color 0.2s;\n      font-size: 0.875rem;\n    }\n\n    .view-mode-btn:hover {\n      background-color: #e9ecef;\n    }\n\n    .view-mode-btn.active {\n      background-color: #341100;\n      color: white;\n    }\n\n    .view-controls {\n      display: flex;\n      align-items: center;\n      gap: 1rem;\n    }\n\n    /* Mobile responsiveness */\n    @media (max-width: 768px) {\n      .content-wrapper {\n        flex-direction: column;\n      }\n\n      .header-section {\n        flex-direction: column;\n        gap: 1rem;\n      }\n\n      .products-table {\n        font-size: 0.8rem;\n      }\n\n      .products-table th,\n      .products-table td {\n        padding: 0.5rem;\n      }\n\n      .property-container h2 {\n        font-size: 1.8rem;\n      }\n\n      .property-container p {\n        font-size: 0.8rem;\n      }\n\n      .filter-controls {\n        flex-direction: column;\n        gap: 1rem;\n        align-items: stretch;\n      }\n\n      .view-controls {\n        flex-direction: column;\n        gap: 0.5rem;\n        align-items: center;\n      }\n\n      .view-mode-toggle {\n        width: 100%;\n        max-width: 300px;\n      }\n\n      .view-mode-btn {\n        flex: 1;\n      }\n    }\n\n    .actions-column {\n      text-align: center;\n      width: 120px;\n    }\n\n    .actions-buttons {\n      display: flex;\n      gap: 0.25rem;\n      justify-content: center;\n      flex-wrap: wrap;\n    }\n\n    .action-btn {\n      background-color: transparent;\n      border: 1px solid #341100;\n      color: #341100;\n      padding: 0.25rem 0.5rem;\n      border-radius: 3px;\n      cursor: pointer;\n      font-size: 0.75rem;\n      transition: all 0.2s;\n      min-width: 50px;\n    }\n\n    .action-btn:hover {\n      background-color: #341100;\n      color: white;\n    }\n\n    .action-btn.delete {\n      border-color: #dc3545;\n      color: #dc3545;\n    }\n\n    .action-btn.delete:hover {\n      background-color: #dc3545;\n      color: white;\n    }\n\n    .action-btn:disabled {\n      opacity: 0.5;\n      cursor: not-allowed;\n    }\n\n    .action-btn:disabled:hover {\n      background-color: transparent;\n      color: #341100;\n    }\n\n    .action-btn.delete:disabled:hover {\n      background-color: transparent;\n      color: #dc3545;\n    }\n\n    @media (max-width: 768px) {\n      .actions-column {\n        width: 100px;\n      }\n\n      .actions-buttons {\n        flex-direction: column;\n        gap: 0.125rem;\n      }\n\n      .action-btn {\n        font-size: 0.7rem;\n        padding: 0.2rem 0.4rem;\n        min-width: 40px;\n      }\n    }\n\n    /* Modal styles */\n    .modal-overlay {\n      position: fixed;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      background-color: rgba(0, 0, 0, 0.5);\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      z-index: 1000;\n      animation: fadeIn 0.2s ease-out;\n    }\n\n    .modal {\n      background: white;\n      border-radius: 8px;\n      box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);\n      max-width: 500px;\n      width: 90%;\n      max-height: 90vh;\n      overflow-y: auto;\n      animation: slideIn 0.2s ease-out;\n    }\n\n    .modal-header {\n      padding: 1.5rem 1.5rem 0;\n      border-bottom: 1px solid #eee;\n    }\n\n    .modal-title {\n      font-size: 1.25rem;\n      font-weight: 600;\n      color: #333;\n      margin: 0 0 1rem 0;\n    }\n\n    .modal-body {\n      padding: 1.5rem;\n    }\n\n    .modal-footer {\n      padding: 0 1.5rem 1.5rem;\n      display: flex;\n      gap: 0.75rem;\n      justify-content: flex-end;\n    }\n\n    .modal-input {\n      width: 100%;\n      padding: 0.75rem;\n      border: 1px solid #ddd;\n      border-radius: 4px;\n      font-size: 1rem;\n      margin-top: 0.5rem;\n    }\n\n    .modal-input:focus {\n      outline: none;\n      border-color: #341100;\n      box-shadow: 0 0 0 2px rgba(52, 17, 0, 0.1);\n    }\n\n    .modal-text {\n      color: #555;\n      line-height: 1.5;\n      margin-bottom: 1rem;\n    }\n\n    .modal-btn {\n      padding: 0.75rem 1.5rem;\n      border: none;\n      border-radius: 4px;\n      font-size: 0.9rem;\n      font-weight: 500;\n      cursor: pointer;\n      transition: all 0.2s;\n      min-width: 80px;\n    }\n\n    .modal-btn-primary {\n      background-color: #341100;\n      color: white;\n    }\n\n    .modal-btn-primary:hover {\n      background-color: #2a0e00;\n    }\n\n    .modal-btn-danger {\n      background-color: #dc3545;\n      color: white;\n    }\n\n    .modal-btn-danger:hover {\n      background-color: #c82333;\n    }\n\n    .modal-btn-secondary {\n      background-color: #f8f9fa;\n      color: #333;\n      border: 1px solid #ddd;\n    }\n\n    .modal-btn-secondary:hover {\n      background-color: #e9ecef;\n    }\n\n    .modal-btn:disabled {\n      opacity: 0.5;\n      cursor: not-allowed;\n    }\n\n    @keyframes fadeIn {\n      from {\n        opacity: 0;\n      }\n      to {\n        opacity: 1;\n      }\n    }\n\n    @keyframes slideIn {\n      from {\n        opacity: 0;\n        transform: translateY(-20px);\n      }\n      to {\n        opacity: 1;\n        transform: translateY(0);\n      }\n    }\n\n    @media (max-width: 768px) {\n      .modal {\n        width: 95%;\n        margin: 1rem;\n      }\n\n      .modal-footer {\n        flex-direction: column;\n      }\n\n      .modal-btn {\n        width: 100%;\n      }\n    }\n  `\n\n  /**\n   * The property name for which we will display barcodes and values\n   */\n  @property({ type: String, attribute: \"property-name\" })\n  propertyName = \"\"\n\n  /**\n   * The base URL for properties listing (e.g., \"https://world.openfoodfacts.org/properties\")\n   * @type {string}\n   */\n  @property({ type: String, attribute: \"properties-url\" })\n  propertiesUrl = \"/properties\"\n\n  @state()\n  private products: Array<{ product: string; v: string }> = []\n\n  @state()\n  private filteredProducts: Array<{ product: string; v: string }> = []\n\n  @state()\n  private groupedValues: Array<{ value: string; count: number }> = []\n\n  @state()\n  private filteredValues: Array<{ value: string; count: number }> = []\n\n  @state()\n  private viewMode: \"products\" | \"values\" = \"products\"\n\n  @state()\n  private loading = false\n\n  @state()\n  private error: string | null = null\n\n  @state()\n  private filters = {\n    barcode: \"\",\n    value: \"\",\n  }\n\n  @state()\n  private showReplaceModal = false\n\n  @state()\n  private showDeleteModal = false\n\n  @state()\n  private showMessageModal = false\n\n  @state()\n  private replaceModalData = {\n    value: \"\",\n    newValue: \"\",\n  }\n\n  @state()\n  private deleteModalValue = \"\"\n\n  @state()\n  private messageModalData = {\n    title: \"\",\n    message: \"\",\n    type: \"success\" as \"success\" | \"error\",\n  }\n\n  private filterTimeout: number | null = null\n\n  override async connectedCallback() {\n    super.connectedCallback()\n    if (this.propertyName) {\n      await this.fetchProductsPropertiesMain()\n    }\n    await folksonomyApi.fetchUserInfo()\n  }\n\n  override disconnectedCallback() {\n    super.disconnectedCallback()\n    // Clean up filter timeout\n    if (this.filterTimeout) {\n      clearTimeout(this.filterTimeout)\n      this.filterTimeout = null\n    }\n  }\n\n  private async fetchProductsPropertiesMain() {\n    this.loading = true\n    this.error = null\n\n    try {\n      const data = await folksonomyApi.fetchProductsProperties(this.propertyName)\n\n      this.products = data || []\n      this.filteredProducts = [...this.products]\n\n      // Also prepare grouped data\n      const valueCountMap = new Map<string, number>()\n      this.products.forEach((product) => {\n        const value = product.v\n        valueCountMap.set(value, (valueCountMap.get(value) || 0) + 1)\n      })\n\n      this.groupedValues = Array.from(valueCountMap.entries())\n        .map(([value, count]) => ({ value, count }))\n        .sort((a, b) => b.count - a.count)\n\n      this.filteredValues = [...this.groupedValues]\n    } catch (error) {\n      console.error(\"Error fetching property products:\", error)\n      this.error = \"Failed to load products. Please try again later.\"\n    } finally {\n      this.loading = false\n    }\n  }\n\n  private get canModerateValues(): boolean {\n    const currentUserInfo = userInfo.get()\n    return currentUserInfo?.admin === true || currentUserInfo?.moderator === true\n  }\n\n  private openReplaceModal(value: string) {\n    this.replaceModalData = {\n      value,\n      newValue: \"\",\n    }\n    this.showReplaceModal = true\n  }\n\n  private closeReplaceModal() {\n    this.showReplaceModal = false\n    this.replaceModalData = {\n      value: \"\",\n      newValue: \"\",\n    }\n  }\n\n  private async handleReplaceValue() {\n    const { value, newValue } = this.replaceModalData\n\n    if (!newValue.trim() || newValue.trim() === value) {\n      return\n    }\n\n    try {\n      await folksonomyApi.replaceValue({\n        property: this.propertyName,\n        old_value: value,\n        new_value: newValue.trim(),\n      })\n\n      this.closeReplaceModal()\n      await this.fetchProductsPropertiesMain()\n      this.showMessage(\"success\", msg(\"Success\"), msg(\"Value replaced successfully!\"))\n    } catch (error) {\n      console.error(\"Error replacing value:\", error)\n      this.showMessage(\"error\", msg(\"Error\"), msg(\"Failed to replace value. Please try again.\"))\n    }\n  }\n\n  private openDeleteModal(value: string) {\n    this.deleteModalValue = value\n    this.showDeleteModal = true\n  }\n\n  private closeDeleteModal() {\n    this.showDeleteModal = false\n    this.deleteModalValue = \"\"\n  }\n\n  private async handleDeleteValue() {\n    try {\n      await folksonomyApi.deleteValue({\n        property: this.propertyName,\n        value: this.deleteModalValue,\n      })\n\n      this.closeDeleteModal()\n      await this.fetchProductsPropertiesMain()\n      this.showMessage(\"success\", msg(\"Success\"), msg(\"Value deleted successfully!\"))\n    } catch (error) {\n      console.error(\"Error deleting value:\", error)\n      this.showMessage(\"error\", msg(\"Error\"), msg(\"Failed to delete value. Please try again.\"))\n    }\n  }\n\n  private showMessage(type: \"success\" | \"error\", title: string, message: string) {\n    this.messageModalData = { type, title, message }\n    this.showMessageModal = true\n  }\n\n  private closeMessageModal() {\n    this.showMessageModal = false\n    this.messageModalData = {\n      title: \"\",\n      message: \"\",\n      type: \"success\",\n    }\n  }\n\n  private renderReplaceModal() {\n    if (!this.showReplaceModal) return \"\"\n\n    return html`\n      <div class=\"modal-overlay\" @click=\"${this.closeReplaceModal}\">\n        <div class=\"modal\" @click=\"${(e: Event) => e.stopPropagation()}\">\n          <div class=\"modal-header\">\n            <h3 class=\"modal-title\">${msg(\"Replace Value\")}</h3>\n          </div>\n          <div class=\"modal-body\">\n            <div class=\"modal-text\">\n              ${msg(\n                str`Replace all instances of '${this.replaceModalData.value}' with a new value:`\n              )}\n            </div>\n            <label for=\"new-value\">${msg(\"New value:\")}</label>\n            <input\n              id=\"new-value\"\n              type=\"text\"\n              class=\"modal-input\"\n              .value=\"${this.replaceModalData.newValue}\"\n              @input=\"${(e: Event) => {\n                this.replaceModalData = {\n                  ...this.replaceModalData,\n                  newValue: (e.target as HTMLInputElement).value,\n                }\n              }}\"\n              @keydown=\"${(e: KeyboardEvent) => {\n                if (e.key === \"Enter\") {\n                  this.handleReplaceValue()\n                } else if (e.key === \"Escape\") {\n                  this.closeReplaceModal()\n                }\n              }}\"\n              placeholder=\"${msg(\"Enter new value...\")}\"\n              autofocus\n            />\n          </div>\n          <div class=\"modal-footer\">\n            <button class=\"modal-btn modal-btn-secondary\" @click=\"${this.closeReplaceModal}\">\n              ${msg(\"Cancel\")}\n            </button>\n            <button\n              class=\"modal-btn modal-btn-primary\"\n              @click=\"${this.handleReplaceValue}\"\n              ?disabled=\"${!this.replaceModalData.newValue.trim() ||\n              this.replaceModalData.newValue.trim() === this.replaceModalData.value}\"\n            >\n              ${msg(\"Replace\")}\n            </button>\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  private renderDeleteModal() {\n    if (!this.showDeleteModal) return \"\"\n\n    return html`\n      <div class=\"modal-overlay\" @click=\"${this.closeDeleteModal}\">\n        <div class=\"modal\" @click=\"${(e: Event) => e.stopPropagation()}\">\n          <div class=\"modal-header\">\n            <h3 class=\"modal-title\">${msg(\"Delete Value\")}</h3>\n          </div>\n          <div class=\"modal-body\">\n            <div class=\"modal-text\">\n              ${msg(\n                str`Are you sure you want to delete all instances of the value '${this.deleteModalValue}'?`\n              )}\n            </div>\n            <div class=\"modal-text\">\n              <strong>${msg(\"This action cannot be undone.\")}</strong>\n            </div>\n          </div>\n          <div class=\"modal-footer\">\n            <button class=\"modal-btn modal-btn-secondary\" @click=\"${this.closeDeleteModal}\">\n              ${msg(\"Cancel\")}\n            </button>\n            <button class=\"modal-btn modal-btn-danger\" @click=\"${this.handleDeleteValue}\">\n              ${msg(\"Delete\")}\n            </button>\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  private renderMessageModal() {\n    if (!this.showMessageModal) return \"\"\n\n    return html`\n      <div class=\"modal-overlay\" @click=\"${this.closeMessageModal}\">\n        <div class=\"modal\" @click=\"${(e: Event) => e.stopPropagation()}\">\n          <div class=\"modal-header\">\n            <h3 class=\"modal-title\">${this.messageModalData.title}</h3>\n          </div>\n          <div class=\"modal-body\">\n            <div class=\"modal-text\">${this.messageModalData.message}</div>\n          </div>\n          <div class=\"modal-footer\">\n            <button class=\"modal-btn modal-btn-primary\" @click=\"${this.closeMessageModal}\">\n              ${msg(\"OK\")}\n            </button>\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  private renderValueActions(valueItem: { value: string; count: number }) {\n    return html`\n      <td class=\"actions-column\">\n        <div class=\"actions-buttons\">\n          <button\n            class=\"action-btn\"\n            @click=\"${() => this.openReplaceModal(valueItem.value)}\"\n            title=\"${msg(\"Replace this value across all products\")}\"\n          >\n            ${msg(\"Replace\")}\n          </button>\n          <button\n            class=\"action-btn delete\"\n            @click=\"${() => this.openDeleteModal(valueItem.value)}\"\n            title=\"${msg(\"Delete this value from all products\")}\"\n          >\n            ${msg(\"Delete\")}\n          </button>\n        </div>\n      </td>\n    `\n  }\n\n  private applyFilters() {\n    const { barcode, value } = this.filters\n\n    // Filter products view\n    this.filteredProducts = this.products.filter((item) => {\n      const matchesBarcode = !barcode || item.product.toLowerCase().includes(barcode.toLowerCase())\n      const matchesValue = !value || item.v.toLowerCase().includes(value.toLowerCase())\n      return matchesBarcode && matchesValue\n    })\n\n    // Filter values view (only value filter applies)\n    this.filteredValues = this.groupedValues.filter((item) => {\n      const matchesValue = !value || item.value.toLowerCase().includes(value.toLowerCase())\n      return matchesValue\n    })\n  }\n\n  private handleFilterInput(field: \"barcode\" | \"value\", value: string) {\n    this.filters = {\n      ...this.filters,\n      [field]: value,\n    }\n\n    // Debounce filtering with 300ms delay for live filtering\n    if (this.filterTimeout) {\n      clearTimeout(this.filterTimeout)\n    }\n\n    this.filterTimeout = window.setTimeout(() => {\n      this.applyFilters()\n    }, 300)\n  }\n\n  private resetFilters() {\n    this.filters = {\n      barcode: \"\",\n      value: \"\",\n    }\n    this.filteredProducts = [...this.products]\n    this.filteredValues = [...this.groupedValues]\n  }\n\n  private switchViewMode(mode: \"products\" | \"values\") {\n    this.viewMode = mode\n  }\n\n  private handleDownloadCSV() {\n    // Create CSV content based on current view mode\n    const isProductsView = this.viewMode === \"products\"\n    const headers = isProductsView\n      ? [msg(\"Product Barcode\"), msg(\"Corresponding Value\")]\n      : [msg(\"Value\"), msg(\"Product Count\")]\n\n    const rows = isProductsView\n      ? this.filteredProducts.map((item) => [item.product, item.v])\n      : this.filteredValues.map((item) => [item.value, item.count])\n\n    const today = new Date().toISOString().split(\"T\")[0]\n    const filename = isProductsView\n      ? `folksonomy_property_${today}_${this.propertyName}_products.csv`\n      : `folksonomy_property_${today}_${this.propertyName}_values.csv`\n\n    downloadCSV(rows, filename, headers)\n  }\n\n  private getProductUrl(productCode: string) {\n    return `/product/${productCode}`\n  }\n\n  private getPropertyValueUrl(value: string) {\n    return `/property/${this.propertyName}/value/${value}`\n  }\n\n  private getDocumentationUrl() {\n    return `https://wiki.openfoodfacts.org/Folksonomy/Property/${this.propertyName}`\n  }\n\n  private renderTableHeader() {\n    return html`\n      <thead>\n        <tr>\n          <th class=\"product-code-header\">${msg(\"Product barcode\")}</th>\n          <th class=\"value-header\">${msg(\"Corresponding value\")}</th>\n        </tr>\n        <tr class=\"filter-row\">\n          <td>\n            <input\n              type=\"text\"\n              class=\"filter-input\"\n              placeholder=\"${msg(\"Filter barcodes...\")}\"\n              .value=\"${this.filters.barcode}\"\n              @input=\"${(e: Event) =>\n                this.handleFilterInput(\"barcode\", (e.target as HTMLInputElement).value)}\"\n            />\n          </td>\n          <td>\n            <input\n              type=\"text\"\n              class=\"filter-input\"\n              placeholder=\"${msg(\"Filter values...\")}\"\n              .value=\"${this.filters.value}\"\n              @input=\"${(e: Event) =>\n                this.handleFilterInput(\"value\", (e.target as HTMLInputElement).value)}\"\n            />\n          </td>\n        </tr>\n      </thead>\n    `\n  }\n\n  private renderProductRow(product: { product: string; v: string }) {\n    return html`\n      <tr>\n        <td class=\"product-code\">\n          <a href=\"${this.getProductUrl(product.product)}\" class=\"product-code\">\n            ${product.product}\n          </a>\n        </td>\n        <td class=\"property-value\">\n          <a href=\"${this.getPropertyValueUrl(product.v)}\" class=\"property-value\"> ${product.v} </a>\n        </td>\n      </tr>\n    `\n  }\n\n  private renderValueRow(valueItem: { value: string; count: number }) {\n    return html`\n      <tr>\n        <td class=\"property-value\">\n          <a href=\"${this.getPropertyValueUrl(valueItem.value)}\" class=\"property-value\">\n            ${valueItem.value}\n          </a>\n        </td>\n        <td class=\"count\">${valueItem.count}</td>\n        ${this.canModerateValues ? this.renderValueActions(valueItem) : \"\"}\n      </tr>\n    `\n  }\n\n  private renderGroupedTableHeader() {\n    return html`\n      <thead>\n        <tr>\n          <th class=\"value-header\">${msg(\"Property Value\")}</th>\n          <th class=\"count-header\">${msg(\"Product Count\")}</th>\n          ${this.canModerateValues ? html`<th class=\"actions-column\">${msg(\"Actions\")}</th>` : \"\"}\n        </tr>\n        <tr class=\"filter-row\">\n          <td>\n            <input\n              type=\"text\"\n              class=\"filter-input\"\n              placeholder=\"${msg(\"Filter values...\")}\"\n              .value=\"${this.filters.value}\"\n              @input=\"${(e: Event) =>\n                this.handleFilterInput(\"value\", (e.target as HTMLInputElement).value)}\"\n            />\n          </td>\n          <td></td>\n          ${this.canModerateValues ? html`<td></td>` : \"\"}\n        </tr>\n      </thead>\n    `\n  }\n\n  private renderContent() {\n    if (this.loading) {\n      return html`<div class=\"loading\">${msg(\"Loading products...\")}</div>`\n    }\n\n    if (this.error) {\n      return html`<div class=\"error\">${this.error}</div>`\n    }\n\n    if (this.products.length === 0) {\n      return html`<div class=\"empty-state\">${msg(\"No products found for this property.\")}</div>`\n    }\n\n    const isProductsView = this.viewMode === \"products\"\n    const currentData = isProductsView ? this.filteredProducts : this.filteredValues\n    const totalData = isProductsView ? this.products : this.groupedValues\n\n    return html`\n      <div class=\"table-container\">\n        <div class=\"filter-controls\">\n          <div class=\"view-controls\">\n            <div class=\"view-mode-toggle\">\n              <button\n                class=\"view-mode-btn ${this.viewMode === \"products\" ? \"active\" : \"\"}\"\n                @click=\"${() => this.switchViewMode(\"products\")}\"\n              >\n                ${msg(\"Individual Products\")}\n              </button>\n              <button\n                class=\"view-mode-btn ${this.viewMode === \"values\" ? \"active\" : \"\"}\"\n                @click=\"${() => this.switchViewMode(\"values\")}\"\n              >\n                ${msg(\"Grouped Values\")}\n              </button>\n            </div>\n            <div class=\"rows-counter\">\n              ${isProductsView\n                ? `${msg(\"Products\")}: ${currentData.length} / ${totalData.length}`\n                : `${msg(\"Values\")}: ${currentData.length} / ${totalData.length}`}\n            </div>\n          </div>\n          <div class=\"button-group\">\n            <button class=\"download-btn\" @click=\"${this.handleDownloadCSV}\">\n              ${msg(\"Download CSV\")}\n            </button>\n            <button class=\"reset-btn\" @click=\"${this.resetFilters}\">${msg(\"Reset\")}</button>\n          </div>\n        </div>\n        <table class=\"products-table\" id=\"products-table\">\n          ${isProductsView ? this.renderTableHeader() : this.renderGroupedTableHeader()}\n          <tbody>\n            ${isProductsView\n              ? this.filteredProducts.map((product) => this.renderProductRow(product))\n              : this.filteredValues.map((valueItem) => this.renderValueRow(valueItem))}\n          </tbody>\n        </table>\n      </div>\n    `\n  }\n\n  override render() {\n    if (!this.propertyName) {\n      return html`\n        <div class=\"property-container\">\n          <div class=\"error\">\n            ${msg(\"Please provide a property name using the property-name attribute.\")}\n          </div>\n        </div>\n      `\n    }\n\n    return html`\n      <div class=\"property-container\">\n        <div class=\"content-wrapper\">\n          <div class=\"main-content\">\n            <div class=\"header-section\">\n              <div class=\"property-title-container\">\n                <h2 id=\"property_title\">${msg(\"Folksonomy property\")}: ${this.propertyName}</h2>\n\n                <div id=\"fe_infobox\" class=\"info-box\">\n                  ${msg(\"Tip: you can also find the\")}\n                  <a href=\"${this.propertiesUrl}\" target=\"_blank\"\n                    >${msg(\"list of all properties\")}</a\n                  >.\n                </div>\n\n                <p>\n                  <slot name=\"property-description\">\n                    ${msg(\"You should find a\")}\n                    <a\n                      href=\"${this.getDocumentationUrl()}\"\n                      target=\"_blank\"\n                      rel=\"noopener noreferrer\"\n                    >\n                      ${msg(\"dedicated documentation\")}\n                    </a>\n                    ${msg(\"about this property on Open Food Facts wiki\")}\n                  </slot>\n                </p>\n\n                <p>${msg(\"List of products using this property\")}:</p>\n              </div>\n            </div>\n\n            ${this.renderContent()}\n          </div>\n        </div>\n      </div>\n\n      ${this.renderReplaceModal()} ${this.renderDeleteModal()} ${this.renderMessageModal()}\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"folksonomy-property-products\": FolksonomyPropertyProducts\n  }\n}\n","import { LitElement, html, css, nothing } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { classMap } from \"lit/directives/class-map.js\"\nimport { localized, msg, str } from \"@lit/localize\"\nimport { KP_ATTRIBUTE_IMG } from \"../../utils/openfoodfacts\"\nimport { getImageUrl } from \"../../signals/app\"\nimport { darkModeListener } from \"../../utils/dark-mode-listener\"\n\ninterface NavigationState {\n  to: {\n    params: {\n      barcode: string\n    }\n  } | null\n}\n\ninterface PersonalScore {\n  score: number\n  matchStatus:\n    | \"very_good_match\"\n    | \"good_match\"\n    | \"poor_match\"\n    | \"does_not_match\"\n    | \"may_not_match\"\n    | \"unknown_match\"\n  totalWeights: number\n  totalWeightedScore: number\n}\n\ninterface Product {\n  code: string\n  product_name: string\n  brands: string\n  quantity: string\n  image_front_small_url: string\n  product_type: string\n  nutriscore_grade?: string\n  nova_group?: number\n  greenscore_grade?: string // Assuming this is the name of the ecoscore attribute (need to confirm with actual data, when available)\n}\n\n/**\n * Product Card component to display a food product with its image and nutrition scores\n * @element product-card\n */\n@customElement(\"product-card\")\n@localized()\nexport class ProductCard extends LitElement {\n  static override styles = css`\n    :host {\n      display: block;\n      font-family: \"Plus Jakarta Sans Variable\", system-ui, sans-serif;\n    }\n\n    .card-container {\n      display: flex;\n      flex-direction: column;\n      height: 100%;\n      width: 100%;\n      max-width: 100%;\n      border-radius: 1rem;\n      box-shadow:\n        0 4px 6px -1px rgba(0, 0, 0, 0.1),\n        0 2px 4px -1px rgba(0, 0, 0, 0.06);\n      cursor: pointer;\n      position: relative;\n      background-color: white;\n      overflow: hidden;\n    }\n\n    .card-content {\n      display: flex;\n      flex: 1;\n      border-radius: 1rem;\n      height: 100%;\n    }\n\n    .dark-mode {\n      background-color: #2d2724;\n      color: #f9f7f5;\n    }\n\n    .image-container {\n      height: 100%;\n      width: 40%;\n      text-align: center;\n      font-size: 0.875rem;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n\n    @media (min-width: 640px) {\n      .image-container {\n        width: 7rem;\n      }\n    }\n\n    @media (min-width: 1024px) {\n      .image-container {\n        width: 9rem;\n      }\n    }\n\n    .loading-container {\n      display: flex;\n      height: 100%;\n      width: 100%;\n      align-items: center;\n      justify-content: center;\n    }\n\n    .loading-ring {\n      display: inline-block;\n      position: relative;\n      width: 64px;\n      height: 64px;\n    }\n\n    .loading-ring:after {\n      content: \" \";\n      display: block;\n      width: 46px;\n      height: 46px;\n      margin: 8px;\n      border-radius: 50%;\n      border: 5px solid currentColor;\n      border-color: currentColor transparent currentColor transparent;\n      animation: loading-ring 1.2s linear infinite;\n    }\n\n    @keyframes loading-ring {\n      0% {\n        transform: rotate(0deg);\n      }\n      100% {\n        transform: rotate(360deg);\n      }\n    }\n\n    .product-image {\n      height: 100%;\n      width: 100%;\n      overflow: hidden;\n      object-fit: cover;\n      border-top-left-radius: 1rem;\n      border-bottom-left-radius: 1rem;\n    }\n\n    .placeholder-container {\n      display: flex;\n      height: 100%;\n      width: 100%;\n      align-items: center;\n      justify-content: center;\n      background-color: transparent;\n      color: black;\n    }\n\n    .placeholder-image {\n      height: 100%;\n      width: 100%;\n      border-radius: 0.5rem;\n      background-color: transparent;\n      object-fit: cover;\n      opacity: 0.7;\n      overflow: hidden;\n    }\n\n    .dark-mode .placeholder-image {\n      filter: invert(1);\n    }\n\n    .content-container {\n      display: flex;\n      flex-direction: column;\n      width: 60%;\n      align-items: center;\n      justify-content: space-evenly;\n      padding: 0.5rem;\n      padding-left: 0.75rem;\n      font-weight: 600;\n      padding-top: 1rem;\n    }\n\n    @media (min-width: 640px) {\n      .content-container {\n        width: 10rem;\n      }\n    }\n\n    @media (min-width: 768px) {\n      .content-container {\n        width: 14rem;\n      }\n    }\n\n    @media (min-width: 1024px) {\n      .content-container {\n        width: 13rem;\n      }\n    }\n\n    .title {\n      width: 100%;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;\n      font-size: 1.125rem;\n      font-weight: 600;\n    }\n\n    @media (min-width: 640px) {\n      .title {\n        font-size: 1rem;\n      }\n    }\n\n    .brand-quantity {\n      display: flex;\n      width: 100%;\n      justify-content: flex-start;\n    }\n\n    .brand-quantity p {\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;\n      font-size: 0.875rem;\n      margin: 0;\n    }\n\n    .scores-container {\n      display: flex;\n      height: 3rem;\n      width: 100%;\n      flex-direction: row;\n      margin-top: 0.5rem;\n      align-items: stretch;\n      justify-content: space-evenly;\n      gap: 0.25rem;\n    }\n\n    .score-item {\n      display: flex;\n      align-items: center;\n    }\n\n    .score-image {\n      height: 100%;\n      max-height: 2.5rem;\n    }\n\n    @media (min-width: 640px) {\n      .score-image {\n        max-height: 2.5rem;\n      }\n    }\n\n    .match-tag {\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      color: white;\n      padding: 0.25rem 0.5rem;\n      font-size: 0.75rem;\n      font-weight: 600;\n      text-align: center;\n      border-top-left-radius: 1rem;\n      border-top-right-radius: 1rem;\n      z-index: 10;\n      width: 100%;\n      box-sizing: border-box;\n    }\n\n    /* Match score color variants */\n    .match-tag-very-good-match {\n      background-color: #10b981; /* Dark green */\n    }\n\n    .match-tag-good-match {\n      background-color: #34d399; /* Light green */\n    }\n\n    .match-tag-poor-match {\n      background-color: #f59e0b; /* Yellow/Orange */\n    }\n\n    .match-tag-does-not-match {\n      background-color: #ef4444; /* Red */\n    }\n\n    .match-tag-may-not-match {\n      background-color: #f97316; /* Orange */\n    }\n\n    .match-tag-unknown-match {\n      background-color: #6b7280; /* Gray */\n    }\n  `\n\n  /**\n   * The product object containing product details\n   */\n  @property({ type: Object })\n  product: Product = {\n    code: \"\",\n    product_name: \"\",\n    brands: \"\",\n    quantity: \"\",\n    image_front_small_url: \"\",\n    product_type: \"\",\n    nutriscore_grade: undefined,\n    nova_group: undefined,\n    greenscore_grade: undefined,\n  }\n\n  /**\n   * The personal score object containing match scoring information\n   */\n  @property({ type: Object })\n  personalScore: PersonalScore | undefined = undefined\n\n  /**\n   * Whether to show the match score tag on the product card\n   */\n  @property({ type: Boolean })\n  showMatchTag: boolean = false\n\n  /**\n   * Indicates if we're currently navigating to this product\n   */\n  @property({ type: Object })\n  navigating: NavigationState = {\n    to: null,\n  }\n\n  @state()\n  nutriscoreSrc = \"\"\n\n  @state()\n  novaSrc = \"\"\n\n  @state()\n  greenscoreSrc = \"\"\n\n  /**\n   * Placeholder image URL for products without an image\n   */\n  @property({ type: String })\n  placeholderImage = getImageUrl(\"Placeholder.svg\")\n\n  /**\n   * Whether to apply dark mode styling (auto-detected from prefers-color-scheme)\n   */\n  isDarkMode = darkModeListener.darkMode\n  private _darkModeCb = (isDark: boolean) => {\n    this.isDarkMode = isDark\n    this.requestUpdate()\n  }\n\n  override connectedCallback() {\n    super.connectedCallback()\n    darkModeListener.subscribe(this._darkModeCb)\n  }\n\n  override disconnectedCallback() {\n    darkModeListener.unsubscribe(this._darkModeCb)\n    super.disconnectedCallback()\n  }\n\n  /**\n   * Updates score image URLs based on the product's nutrition grades, nova group, and greenscore\n   */\n  override updated(changedProperties: Map<string, any>) {\n    super.updated(changedProperties)\n    this.nutriscoreSrc = KP_ATTRIBUTE_IMG(\n      `nutriscore-${this.product.nutriscore_grade?.toLowerCase() || \"unknown\"}.svg`\n    )\n    this.novaSrc = KP_ATTRIBUTE_IMG(`nova-group-${this.product.nova_group || \"unknown\"}.svg`)\n    this.greenscoreSrc = KP_ATTRIBUTE_IMG(\n      `green-score-${this.product.greenscore_grade?.toLowerCase() || \"unknown\"}.svg`\n    )\n  }\n\n  /**\n   * Gets match tag information based on personalScore from product\n   */\n  private getMatchTagInfo(): { text: string; cssClass: string } {\n    if (this.personalScore) {\n      const { score, matchStatus } = this.personalScore\n      switch (matchStatus) {\n        case \"very_good_match\":\n          return {\n            text: msg(str`Very Good Match ${score}%`),\n            cssClass: \"match-tag-very-good-match\",\n          }\n        case \"good_match\":\n          return {\n            text: msg(str`Good Match ${score}%`),\n            cssClass: \"match-tag-good-match\",\n          }\n        case \"poor_match\":\n          return {\n            text: msg(str`Poor Match ${score}%`),\n            cssClass: \"match-tag-poor-match\",\n          }\n        case \"does_not_match\":\n          return {\n            text: msg(\"Does Not Match\"),\n            cssClass: \"match-tag-does-not-match\",\n          }\n        case \"may_not_match\":\n          return {\n            text: msg(\"May Not Match\"),\n            cssClass: \"match-tag-may-not-match\",\n          }\n        case \"unknown_match\":\n          return {\n            text: msg(\"Unknown Match\"),\n            cssClass: \"match-tag-unknown-match\",\n          }\n        default:\n          return {\n            text: msg(\"Unknown Match\"),\n            cssClass: \"match-tag-unknown-match\",\n          }\n      }\n    }\n\n    // Return default if no personalScore available\n    return {\n      text: msg(\"No Score Available\"),\n      cssClass: \"match-tag-unknown-match\",\n    }\n  }\n\n  override render() {\n    const isNavigatingToProduct = this.navigating.to?.params?.barcode === this.product.code\n    const hasProductImage = Boolean(this.product.image_front_small_url)\n    const matchTagInfo = this.getMatchTagInfo()\n    const cardClasses = {\n      \"card-container\": true,\n      \"dark-mode\": this.isDarkMode,\n    }\n\n    return html`\n      <div class=${classMap(cardClasses)}>\n        ${this.showMatchTag\n          ? html`<div class=\"match-tag ${matchTagInfo.cssClass}\">${matchTagInfo.text}</div>`\n          : nothing}\n        <div class=\"card-content\">\n          <div class=\"image-container\">\n            ${isNavigatingToProduct\n              ? html`\n                  <div class=\"loading-container\">\n                    <span class=\"loading-ring\"></span>\n                  </div>\n                `\n              : hasProductImage\n                ? html`\n                    <div class=\"loading-container\">\n                      <img\n                        src=${this.product.image_front_small_url}\n                        class=\"product-image\"\n                        alt=\"Product front\"\n                      />\n                    </div>\n                  `\n                : html`\n                    <div class=\"placeholder-container\">\n                      <img\n                        src=${this.placeholderImage}\n                        class=\"placeholder-image\"\n                        alt=\"Product front\"\n                      />\n                    </div>\n                  `}\n          </div>\n          <div class=\"content-container\">\n            <div\n              class=\"title\"\n              title=${this.product.product_name ? this.product.product_name : this.product.code}\n            >\n              ${this.product.product_name ? this.product.product_name : this.product.code}\n            </div>\n\n            <div class=\"brand-quantity\">\n              <p title=\"${this.product.brands} - ${this.product.quantity}\">\n                ${this.product.brands} - ${this.product.quantity}\n              </p>\n            </div>\n\n            ${this.product.product_type === \"food\"\n              ? html`\n                  <div class=\"scores-container\">\n                    <div class=\"score-item\">\n                      <img src=${this.nutriscoreSrc} alt=\"nutriscore\" class=\"score-image\" />\n                    </div>\n                    <div class=\"score-item\">\n                      <img src=${this.novaSrc} alt=\"nova\" class=\"score-image\" />\n                    </div>\n                    <div class=\"score-item\">\n                      <img src=${this.greenscoreSrc} alt=\"greenscore\" class=\"score-image\" />\n                    </div>\n                  </div>\n                `\n              : nothing}\n          </div>\n        </div>\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"product-card\": ProductCard\n  }\n}\n","/**\n * marked v16.3.0 - a markdown parser\n * Copyright (c) 2011-2025, Christopher Jeffrey. (MIT Licensed)\n * https://github.com/markedjs/marked\n */\n\n/**\n * DO NOT EDIT THIS FILE\n * The code in this file is generated from files in ./src/\n */\n\nfunction L(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var O=L();function G(l){O=l}var E={exec:()=>null};function h(l,e=\"\"){let t=typeof l==\"string\"?l:l.source,n={replace:(r,i)=>{let s=typeof i==\"string\"?i:i.source;return s=s.replace(m.caret,\"$1\"),t=t.replace(r,s),n},getRegex:()=>new RegExp(t,e)};return n}var m={codeRemoveIndent:/^(?: {1,4}| {0,3}\\t)/gm,outputLinkReplace:/\\\\([\\[\\]])/g,indentCodeCompensation:/^(\\s+)(?:```)/,beginningSpace:/^\\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\\n/g,tabCharGlobal:/\\t/g,multipleSpaceGlobal:/\\s+/g,blankLine:/^[ \\t]*$/,doubleBlankLine:/\\n[ \\t]*\\n[ \\t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \\t]?/gm,listReplaceTabs:/^\\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\\[[ xX]\\] /,listReplaceTask:/^\\[[ xX]\\] +/,anyLine:/\\n.*\\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\\||\\| *$/g,tableRowBlankLine:/\\n[ \\t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\\s|>)/i,endPreScriptTag:/^<\\/(pre|code|kbd|script)(\\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'\"]*[^\\s])\\s+(['\"])(.*)\\2/,unicodeAlphaNumeric:/[\\p{L}\\p{N}]/u,escapeTest:/[&<>\"']/,escapeReplace:/[&<>\"']/g,escapeTestNoEncode:/[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,escapeReplaceNoEncode:/[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,unescapeTest:/&(#(?:\\d+)|(?:#x[0-9A-Fa-f]+)|(?:\\w+));?/ig,caret:/(^|[^\\[])\\^/g,percentDecode:/%25/g,findPipe:/\\|/g,splitPipe:/ \\|/,slashPipe:/\\\\\\|/g,carriageReturn:/\\r\\n|\\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\\S*/,endingNewline:/\\n$/,listItemRegex:l=>new RegExp(`^( {0,3}${l})((?:[\t ][^\\\\n]*)?(?:\\\\n|$))`),nextBulletRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ \t][^\\\\n]*)?(?:\\\\n|$))`),hrRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`),fencesBeginRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}(?:\\`\\`\\`|~~~)`),headingBeginRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}#`),htmlBeginRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}<(?:[a-z].*>|!--)`,\"i\")},xe=/^(?:[ \\t]*(?:\\n|$))+/,be=/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,Re=/^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,C=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,Oe=/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,j=/(?:[*+-]|\\d{1,9}[.)])/,se=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,ie=h(se).replace(/bull/g,j).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/\\|table/g,\"\").getRegex(),Te=h(se).replace(/bull/g,j).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/table/g,/ {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/).getRegex(),F=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\\n)[^\\n]+)*)/,we=/^[^\\n]+/,Q=/(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/,ye=h(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace(\"label\",Q).replace(\"title\",/(?:\"(?:\\\\\"?|[^\"\\\\])*\"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/).getRegex(),Pe=h(/^( {0,3}bull)([ \\t][^\\n]+?)?(?:\\n|$)/).replace(/bull/g,j).getRegex(),v=\"address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul\",U=/<!--(?:-?>|[\\s\\S]*?(?:-->|$))/,Se=h(\"^ {0,3}(?:<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n+|$)|comment[^\\\\n]*(\\\\n+|$)|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>\\\\n*|$)|<![A-Z][\\\\s\\\\S]*?(?:>\\\\n*|$)|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>\\\\n*|$)|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n[ \t]*)+\\\\n|$)|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \t]*)+\\\\n|$)|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \t]*)+\\\\n|$))\",\"i\").replace(\"comment\",U).replace(\"tag\",v).replace(\"attribute\",/ +[a-zA-Z:_][\\w.:-]*(?: *= *\"[^\"\\n]*\"| *= *'[^'\\n]*'| *= *[^\\s\"'=<>`]+)?/).getRegex(),oe=h(F).replace(\"hr\",C).replace(\"heading\",\" {0,3}#{1,6}(?:\\\\s|$)\").replace(\"|lheading\",\"\").replace(\"|table\",\"\").replace(\"blockquote\",\" {0,3}>\").replace(\"fences\",\" {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n\").replace(\"list\",\" {0,3}(?:[*+-]|1[.)]) \").replace(\"html\",\"</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)\").replace(\"tag\",v).getRegex(),$e=h(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace(\"paragraph\",oe).getRegex(),K={blockquote:$e,code:be,def:ye,fences:Re,heading:Oe,hr:C,html:Se,lheading:ie,list:Pe,newline:xe,paragraph:oe,table:E,text:we},re=h(\"^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)\").replace(\"hr\",C).replace(\"heading\",\" {0,3}#{1,6}(?:\\\\s|$)\").replace(\"blockquote\",\" {0,3}>\").replace(\"code\",\"(?: {4}| {0,3}\t)[^\\\\n]\").replace(\"fences\",\" {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n\").replace(\"list\",\" {0,3}(?:[*+-]|1[.)]) \").replace(\"html\",\"</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)\").replace(\"tag\",v).getRegex(),_e={...K,lheading:Te,table:re,paragraph:h(F).replace(\"hr\",C).replace(\"heading\",\" {0,3}#{1,6}(?:\\\\s|$)\").replace(\"|lheading\",\"\").replace(\"table\",re).replace(\"blockquote\",\" {0,3}>\").replace(\"fences\",\" {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n\").replace(\"list\",\" {0,3}(?:[*+-]|1[.)]) \").replace(\"html\",\"</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)\").replace(\"tag\",v).getRegex()},Le={...K,html:h(`^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\\\s[^'\"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))`).replace(\"comment\",U).replace(/tag/g,\"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b\").getRegex(),def:/^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +([\"(][^\\n]+[\")]))? *(?:\\n+|$)/,heading:/^(#{1,6})(.*)(?:\\n+|$)/,fences:E,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:h(F).replace(\"hr\",C).replace(\"heading\",` *#{1,6} *[^\n]`).replace(\"lheading\",ie).replace(\"|table\",\"\").replace(\"blockquote\",\" {0,3}>\").replace(\"|fences\",\"\").replace(\"|list\",\"\").replace(\"|html\",\"\").replace(\"|tag\",\"\").getRegex()},Me=/^\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,ze=/^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,ae=/^( {2,}|\\\\)\\n(?!\\s*$)/,Ae=/^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,D=/[\\p{P}\\p{S}]/u,W=/[\\s\\p{P}\\p{S}]/u,le=/[^\\s\\p{P}\\p{S}]/u,Ee=h(/^((?![*_])punctSpace)/,\"u\").replace(/punctSpace/g,W).getRegex(),ue=/(?!~)[\\p{P}\\p{S}]/u,Ce=/(?!~)[\\s\\p{P}\\p{S}]/u,Ie=/(?:[^\\s\\p{P}\\p{S}]|~)/u,Be=/\\[[^\\[\\]]*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)|`[^`]*?`|<(?! )[^<>]*?>/g,pe=/^(?:\\*+(?:((?!\\*)punct)|[^\\s*]))|^_+(?:((?!_)punct)|([^\\s_]))/,qe=h(pe,\"u\").replace(/punct/g,D).getRegex(),ve=h(pe,\"u\").replace(/punct/g,ue).getRegex(),ce=\"^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)\",De=h(ce,\"gu\").replace(/notPunctSpace/g,le).replace(/punctSpace/g,W).replace(/punct/g,D).getRegex(),He=h(ce,\"gu\").replace(/notPunctSpace/g,Ie).replace(/punctSpace/g,Ce).replace(/punct/g,ue).getRegex(),Ze=h(\"^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)\",\"gu\").replace(/notPunctSpace/g,le).replace(/punctSpace/g,W).replace(/punct/g,D).getRegex(),Ge=h(/\\\\(punct)/,\"gu\").replace(/punct/g,D).getRegex(),Ne=h(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/).replace(\"scheme\",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace(\"email\",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),je=h(U).replace(\"(?:-->|$)\",\"-->\").getRegex(),Fe=h(\"^comment|^</[a-zA-Z][\\\\w:-]*\\\\s*>|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>|^<\\\\?[\\\\s\\\\S]*?\\\\?>|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>\").replace(\"comment\",je).replace(\"attribute\",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*\"[^\"]*\"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s\"'=<>`]+)?/).getRegex(),q=/(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`[^`]*`|[^\\[\\]\\\\`])*?/,Qe=h(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]*(?:\\n[ \\t]*)?)(title))?\\s*\\)/).replace(\"label\",q).replace(\"href\",/<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]*/).replace(\"title\",/\"(?:\\\\\"?|[^\"\\\\])*\"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),he=h(/^!?\\[(label)\\]\\[(ref)\\]/).replace(\"label\",q).replace(\"ref\",Q).getRegex(),de=h(/^!?\\[(ref)\\](?:\\[\\])?/).replace(\"ref\",Q).getRegex(),Ue=h(\"reflink|nolink(?!\\\\()\",\"g\").replace(\"reflink\",he).replace(\"nolink\",de).getRegex(),X={_backpedal:E,anyPunctuation:Ge,autolink:Ne,blockSkip:Be,br:ae,code:ze,del:E,emStrongLDelim:qe,emStrongRDelimAst:De,emStrongRDelimUnd:Ze,escape:Me,link:Qe,nolink:de,punctuation:Ee,reflink:he,reflinkSearch:Ue,tag:Fe,text:Ae,url:E},Ke={...X,link:h(/^!?\\[(label)\\]\\((.*?)\\)/).replace(\"label\",q).getRegex(),reflink:h(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace(\"label\",q).getRegex()},N={...X,emStrongRDelimAst:He,emStrongLDelim:ve,url:h(/^((?:ftp|https?):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/,\"i\").replace(\"email\",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'\"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'\"~)]+(?!$))+/,del:/^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|https?:\\/\\/|ftp:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)))/},We={...N,br:h(ae).replace(\"{2,}\",\"*\").getRegex(),text:h(N.text).replace(\"\\\\b_\",\"\\\\b_| {2,}\\\\n\").replace(/\\{2,\\}/g,\"*\").getRegex()},I={normal:K,gfm:_e,pedantic:Le},M={normal:X,gfm:N,breaks:We,pedantic:Ke};var Xe={\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#39;\"},ke=l=>Xe[l];function w(l,e){if(e){if(m.escapeTest.test(l))return l.replace(m.escapeReplace,ke)}else if(m.escapeTestNoEncode.test(l))return l.replace(m.escapeReplaceNoEncode,ke);return l}function J(l){try{l=encodeURI(l).replace(m.percentDecode,\"%\")}catch{return null}return l}function V(l,e){let t=l.replace(m.findPipe,(i,s,o)=>{let a=!1,u=s;for(;--u>=0&&o[u]===\"\\\\\";)a=!a;return a?\"|\":\" |\"}),n=t.split(m.splitPipe),r=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length<e;)n.push(\"\");for(;r<n.length;r++)n[r]=n[r].trim().replace(m.slashPipe,\"|\");return n}function z(l,e,t){let n=l.length;if(n===0)return\"\";let r=0;for(;r<n;){let i=l.charAt(n-r-1);if(i===e&&!t)r++;else if(i!==e&&t)r++;else break}return l.slice(0,n-r)}function ge(l,e){if(l.indexOf(e[1])===-1)return-1;let t=0;for(let n=0;n<l.length;n++)if(l[n]===\"\\\\\")n++;else if(l[n]===e[0])t++;else if(l[n]===e[1]&&(t--,t<0))return n;return t>0?-2:-1}function fe(l,e,t,n,r){let i=e.href,s=e.title||null,o=l[1].replace(r.other.outputLinkReplace,\"$1\");n.state.inLink=!0;let a={type:l[0].charAt(0)===\"!\"?\"image\":\"link\",raw:t,href:i,title:s,text:o,tokens:n.inlineTokens(o)};return n.state.inLink=!1,a}function Je(l,e,t){let n=l.match(t.other.indentCodeCompensation);if(n===null)return e;let r=n[1];return e.split(`\n`).map(i=>{let s=i.match(t.other.beginningSpace);if(s===null)return i;let[o]=s;return o.length>=r.length?i.slice(r.length):i}).join(`\n`)}var y=class{options;rules;lexer;constructor(e){this.options=e||O}space(e){let t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:\"space\",raw:t[0]}}code(e){let t=this.rules.block.code.exec(e);if(t){let n=t[0].replace(this.rules.other.codeRemoveIndent,\"\");return{type:\"code\",raw:t[0],codeBlockStyle:\"indented\",text:this.options.pedantic?n:z(n,`\n`)}}}fences(e){let t=this.rules.block.fences.exec(e);if(t){let n=t[0],r=Je(n,t[3]||\"\",this.rules);return{type:\"code\",raw:n,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,\"$1\"):t[2],text:r}}}heading(e){let t=this.rules.block.heading.exec(e);if(t){let n=t[2].trim();if(this.rules.other.endingHash.test(n)){let r=z(n,\"#\");(this.options.pedantic||!r||this.rules.other.endingSpaceChar.test(r))&&(n=r.trim())}return{type:\"heading\",raw:t[0],depth:t[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(e){let t=this.rules.block.hr.exec(e);if(t)return{type:\"hr\",raw:z(t[0],`\n`)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let n=z(t[0],`\n`).split(`\n`),r=\"\",i=\"\",s=[];for(;n.length>0;){let o=!1,a=[],u;for(u=0;u<n.length;u++)if(this.rules.other.blockquoteStart.test(n[u]))a.push(n[u]),o=!0;else if(!o)a.push(n[u]);else break;n=n.slice(u);let p=a.join(`\n`),c=p.replace(this.rules.other.blockquoteSetextReplace,`\n    $1`).replace(this.rules.other.blockquoteSetextReplace2,\"\");r=r?`${r}\n${p}`:p,i=i?`${i}\n${c}`:c;let f=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(c,s,!0),this.lexer.state.top=f,n.length===0)break;let k=s.at(-1);if(k?.type===\"code\")break;if(k?.type===\"blockquote\"){let x=k,g=x.raw+`\n`+n.join(`\n`),T=this.blockquote(g);s[s.length-1]=T,r=r.substring(0,r.length-x.raw.length)+T.raw,i=i.substring(0,i.length-x.text.length)+T.text;break}else if(k?.type===\"list\"){let x=k,g=x.raw+`\n`+n.join(`\n`),T=this.list(g);s[s.length-1]=T,r=r.substring(0,r.length-k.raw.length)+T.raw,i=i.substring(0,i.length-x.raw.length)+T.raw,n=g.substring(s.at(-1).raw.length).split(`\n`);continue}}return{type:\"blockquote\",raw:r,tokens:s,text:i}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim(),r=n.length>1,i={type:\"list\",raw:\"\",ordered:r,start:r?+n.slice(0,-1):\"\",loose:!1,items:[]};n=r?`\\\\d{1,9}\\\\${n.slice(-1)}`:`\\\\${n}`,this.options.pedantic&&(n=r?n:\"[*+-]\");let s=this.rules.other.listItemRegex(n),o=!1;for(;e;){let u=!1,p=\"\",c=\"\";if(!(t=s.exec(e))||this.rules.block.hr.test(e))break;p=t[0],e=e.substring(p.length);let f=t[2].split(`\n`,1)[0].replace(this.rules.other.listReplaceTabs,H=>\" \".repeat(3*H.length)),k=e.split(`\n`,1)[0],x=!f.trim(),g=0;if(this.options.pedantic?(g=2,c=f.trimStart()):x?g=t[1].length+1:(g=t[2].search(this.rules.other.nonSpaceChar),g=g>4?1:g,c=f.slice(g),g+=t[1].length),x&&this.rules.other.blankLine.test(k)&&(p+=k+`\n`,e=e.substring(k.length+1),u=!0),!u){let H=this.rules.other.nextBulletRegex(g),ee=this.rules.other.hrRegex(g),te=this.rules.other.fencesBeginRegex(g),ne=this.rules.other.headingBeginRegex(g),me=this.rules.other.htmlBeginRegex(g);for(;e;){let Z=e.split(`\n`,1)[0],A;if(k=Z,this.options.pedantic?(k=k.replace(this.rules.other.listReplaceNesting,\"  \"),A=k):A=k.replace(this.rules.other.tabCharGlobal,\"    \"),te.test(k)||ne.test(k)||me.test(k)||H.test(k)||ee.test(k))break;if(A.search(this.rules.other.nonSpaceChar)>=g||!k.trim())c+=`\n`+A.slice(g);else{if(x||f.replace(this.rules.other.tabCharGlobal,\"    \").search(this.rules.other.nonSpaceChar)>=4||te.test(f)||ne.test(f)||ee.test(f))break;c+=`\n`+k}!x&&!k.trim()&&(x=!0),p+=Z+`\n`,e=e.substring(Z.length+1),f=A.slice(g)}}i.loose||(o?i.loose=!0:this.rules.other.doubleBlankLine.test(p)&&(o=!0));let T=null,Y;this.options.gfm&&(T=this.rules.other.listIsTask.exec(c),T&&(Y=T[0]!==\"[ ] \",c=c.replace(this.rules.other.listReplaceTask,\"\"))),i.items.push({type:\"list_item\",raw:p,task:!!T,checked:Y,loose:!1,text:c,tokens:[]}),i.raw+=p}let a=i.items.at(-1);if(a)a.raw=a.raw.trimEnd(),a.text=a.text.trimEnd();else return;i.raw=i.raw.trimEnd();for(let u=0;u<i.items.length;u++)if(this.lexer.state.top=!1,i.items[u].tokens=this.lexer.blockTokens(i.items[u].text,[]),!i.loose){let p=i.items[u].tokens.filter(f=>f.type===\"space\"),c=p.length>0&&p.some(f=>this.rules.other.anyLine.test(f.raw));i.loose=c}if(i.loose)for(let u=0;u<i.items.length;u++)i.items[u].loose=!0;return i}}html(e){let t=this.rules.block.html.exec(e);if(t)return{type:\"html\",block:!0,raw:t[0],pre:t[1]===\"pre\"||t[1]===\"script\"||t[1]===\"style\",text:t[0]}}def(e){let t=this.rules.block.def.exec(e);if(t){let n=t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal,\" \"),r=t[2]?t[2].replace(this.rules.other.hrefBrackets,\"$1\").replace(this.rules.inline.anyPunctuation,\"$1\"):\"\",i=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,\"$1\"):t[3];return{type:\"def\",tag:n,raw:t[0],href:r,title:i}}}table(e){let t=this.rules.block.table.exec(e);if(!t||!this.rules.other.tableDelimiter.test(t[2]))return;let n=V(t[1]),r=t[2].replace(this.rules.other.tableAlignChars,\"\").split(\"|\"),i=t[3]?.trim()?t[3].replace(this.rules.other.tableRowBlankLine,\"\").split(`\n`):[],s={type:\"table\",raw:t[0],header:[],align:[],rows:[]};if(n.length===r.length){for(let o of r)this.rules.other.tableAlignRight.test(o)?s.align.push(\"right\"):this.rules.other.tableAlignCenter.test(o)?s.align.push(\"center\"):this.rules.other.tableAlignLeft.test(o)?s.align.push(\"left\"):s.align.push(null);for(let o=0;o<n.length;o++)s.header.push({text:n[o],tokens:this.lexer.inline(n[o]),header:!0,align:s.align[o]});for(let o of i)s.rows.push(V(o,s.header.length).map((a,u)=>({text:a,tokens:this.lexer.inline(a),header:!1,align:s.align[u]})));return s}}lheading(e){let t=this.rules.block.lheading.exec(e);if(t)return{type:\"heading\",raw:t[0],depth:t[2].charAt(0)===\"=\"?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){let t=this.rules.block.paragraph.exec(e);if(t){let n=t[1].charAt(t[1].length-1)===`\n`?t[1].slice(0,-1):t[1];return{type:\"paragraph\",raw:t[0],text:n,tokens:this.lexer.inline(n)}}}text(e){let t=this.rules.block.text.exec(e);if(t)return{type:\"text\",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){let t=this.rules.inline.escape.exec(e);if(t)return{type:\"escape\",raw:t[0],text:t[1]}}tag(e){let t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:\"html\",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){let t=this.rules.inline.link.exec(e);if(t){let n=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let s=z(n.slice(0,-1),\"\\\\\");if((n.length-s.length)%2===0)return}else{let s=ge(t[2],\"()\");if(s===-2)return;if(s>-1){let a=(t[0].indexOf(\"!\")===0?5:4)+t[1].length+s;t[2]=t[2].substring(0,s),t[0]=t[0].substring(0,a).trim(),t[3]=\"\"}}let r=t[2],i=\"\";if(this.options.pedantic){let s=this.rules.other.pedanticHrefTitle.exec(r);s&&(r=s[1],i=s[3])}else i=t[3]?t[3].slice(1,-1):\"\";return r=r.trim(),this.rules.other.startAngleBracket.test(r)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?r=r.slice(1):r=r.slice(1,-1)),fe(t,{href:r&&r.replace(this.rules.inline.anyPunctuation,\"$1\"),title:i&&i.replace(this.rules.inline.anyPunctuation,\"$1\")},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let r=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal,\" \"),i=t[r.toLowerCase()];if(!i){let s=n[0].charAt(0);return{type:\"text\",raw:s,text:s}}return fe(n,i,n[0],this.lexer,this.rules)}}emStrong(e,t,n=\"\"){let r=this.rules.inline.emStrongLDelim.exec(e);if(!r||r[3]&&n.match(this.rules.other.unicodeAlphaNumeric))return;if(!(r[1]||r[2]||\"\")||!n||this.rules.inline.punctuation.exec(n)){let s=[...r[0]].length-1,o,a,u=s,p=0,c=r[0][0]===\"*\"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,t=t.slice(-1*e.length+s);(r=c.exec(t))!=null;){if(o=r[1]||r[2]||r[3]||r[4]||r[5]||r[6],!o)continue;if(a=[...o].length,r[3]||r[4]){u+=a;continue}else if((r[5]||r[6])&&s%3&&!((s+a)%3)){p+=a;continue}if(u-=a,u>0)continue;a=Math.min(a,a+u+p);let f=[...r[0]][0].length,k=e.slice(0,s+r.index+f+a);if(Math.min(s,a)%2){let g=k.slice(1,-1);return{type:\"em\",raw:k,text:g,tokens:this.lexer.inlineTokens(g)}}let x=k.slice(2,-2);return{type:\"strong\",raw:k,text:x,tokens:this.lexer.inlineTokens(x)}}}}codespan(e){let t=this.rules.inline.code.exec(e);if(t){let n=t[2].replace(this.rules.other.newLineCharGlobal,\" \"),r=this.rules.other.nonSpaceChar.test(n),i=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return r&&i&&(n=n.substring(1,n.length-1)),{type:\"codespan\",raw:t[0],text:n}}}br(e){let t=this.rules.inline.br.exec(e);if(t)return{type:\"br\",raw:t[0]}}del(e){let t=this.rules.inline.del.exec(e);if(t)return{type:\"del\",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2])}}autolink(e){let t=this.rules.inline.autolink.exec(e);if(t){let n,r;return t[2]===\"@\"?(n=t[1],r=\"mailto:\"+n):(n=t[1],r=n),{type:\"link\",raw:t[0],text:n,href:r,tokens:[{type:\"text\",raw:n,text:n}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let n,r;if(t[2]===\"@\")n=t[0],r=\"mailto:\"+n;else{let i;do i=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??\"\";while(i!==t[0]);n=t[0],t[1]===\"www.\"?r=\"http://\"+t[0]:r=t[0]}return{type:\"link\",raw:t[0],text:n,href:r,tokens:[{type:\"text\",raw:n,text:n}]}}}inlineText(e){let t=this.rules.inline.text.exec(e);if(t){let n=this.lexer.state.inRawBlock;return{type:\"text\",raw:t[0],text:t[0],escaped:n}}}};var b=class l{tokens;options;state;tokenizer;inlineQueue;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||O,this.options.tokenizer=this.options.tokenizer||new y,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let t={other:m,block:I.normal,inline:M.normal};this.options.pedantic?(t.block=I.pedantic,t.inline=M.pedantic):this.options.gfm&&(t.block=I.gfm,this.options.breaks?t.inline=M.breaks:t.inline=M.gfm),this.tokenizer.rules=t}static get rules(){return{block:I,inline:M}}static lex(e,t){return new l(t).lex(e)}static lexInline(e,t){return new l(t).inlineTokens(e)}lex(e){e=e.replace(m.carriageReturn,`\n`),this.blockTokens(e,this.tokens);for(let t=0;t<this.inlineQueue.length;t++){let n=this.inlineQueue[t];this.inlineTokens(n.src,n.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[],n=!1){for(this.options.pedantic&&(e=e.replace(m.tabCharGlobal,\"    \").replace(m.spaceLine,\"\"));e;){let r;if(this.options.extensions?.block?.some(s=>(r=s.call({lexer:this},e,t))?(e=e.substring(r.raw.length),t.push(r),!0):!1))continue;if(r=this.tokenizer.space(e)){e=e.substring(r.raw.length);let s=t.at(-1);r.raw.length===1&&s!==void 0?s.raw+=`\n`:t.push(r);continue}if(r=this.tokenizer.code(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type===\"paragraph\"||s?.type===\"text\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.text,this.inlineQueue.at(-1).src=s.text):t.push(r);continue}if(r=this.tokenizer.fences(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.heading(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.hr(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.blockquote(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.list(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.html(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.def(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type===\"paragraph\"||s?.type===\"text\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.raw,this.inlineQueue.at(-1).src=s.text):this.tokens.links[r.tag]||(this.tokens.links[r.tag]={href:r.href,title:r.title},t.push(r));continue}if(r=this.tokenizer.table(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.lheading(e)){e=e.substring(r.raw.length),t.push(r);continue}let i=e;if(this.options.extensions?.startBlock){let s=1/0,o=e.slice(1),a;this.options.extensions.startBlock.forEach(u=>{a=u.call({lexer:this},o),typeof a==\"number\"&&a>=0&&(s=Math.min(s,a))}),s<1/0&&s>=0&&(i=e.substring(0,s+1))}if(this.state.top&&(r=this.tokenizer.paragraph(i))){let s=t.at(-1);n&&s?.type===\"paragraph\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):t.push(r),n=i.length!==e.length,e=e.substring(r.raw.length);continue}if(r=this.tokenizer.text(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type===\"text\"?(s.raw+=(s.raw.endsWith(`\n`)?\"\":`\n`)+r.raw,s.text+=`\n`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):t.push(r);continue}if(e){let s=\"Infinite loop on byte: \"+e.charCodeAt(0);if(this.options.silent){console.error(s);break}else throw new Error(s)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let n=e,r=null;if(this.tokens.links){let o=Object.keys(this.tokens.links);if(o.length>0)for(;(r=this.tokenizer.rules.inline.reflinkSearch.exec(n))!=null;)o.includes(r[0].slice(r[0].lastIndexOf(\"[\")+1,-1))&&(n=n.slice(0,r.index)+\"[\"+\"a\".repeat(r[0].length-2)+\"]\"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(r=this.tokenizer.rules.inline.anyPunctuation.exec(n))!=null;)n=n.slice(0,r.index)+\"++\"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;(r=this.tokenizer.rules.inline.blockSkip.exec(n))!=null;)n=n.slice(0,r.index)+\"[\"+\"a\".repeat(r[0].length-2)+\"]\"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);n=this.options.hooks?.emStrongMask?.call({lexer:this},n)??n;let i=!1,s=\"\";for(;e;){i||(s=\"\"),i=!1;let o;if(this.options.extensions?.inline?.some(u=>(o=u.call({lexer:this},e,t))?(e=e.substring(o.raw.length),t.push(o),!0):!1))continue;if(o=this.tokenizer.escape(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.tag(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.link(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(o.raw.length);let u=t.at(-1);o.type===\"text\"&&u?.type===\"text\"?(u.raw+=o.raw,u.text+=o.text):t.push(o);continue}if(o=this.tokenizer.emStrong(e,n,s)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.codespan(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.br(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.del(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.autolink(e)){e=e.substring(o.raw.length),t.push(o);continue}if(!this.state.inLink&&(o=this.tokenizer.url(e))){e=e.substring(o.raw.length),t.push(o);continue}let a=e;if(this.options.extensions?.startInline){let u=1/0,p=e.slice(1),c;this.options.extensions.startInline.forEach(f=>{c=f.call({lexer:this},p),typeof c==\"number\"&&c>=0&&(u=Math.min(u,c))}),u<1/0&&u>=0&&(a=e.substring(0,u+1))}if(o=this.tokenizer.inlineText(a)){e=e.substring(o.raw.length),o.raw.slice(-1)!==\"_\"&&(s=o.raw.slice(-1)),i=!0;let u=t.at(-1);u?.type===\"text\"?(u.raw+=o.raw,u.text+=o.text):t.push(o);continue}if(e){let u=\"Infinite loop on byte: \"+e.charCodeAt(0);if(this.options.silent){console.error(u);break}else throw new Error(u)}}return t}};var P=class{options;parser;constructor(e){this.options=e||O}space(e){return\"\"}code({text:e,lang:t,escaped:n}){let r=(t||\"\").match(m.notSpaceStart)?.[0],i=e.replace(m.endingNewline,\"\")+`\n`;return r?'<pre><code class=\"language-'+w(r)+'\">'+(n?i:w(i,!0))+`</code></pre>\n`:\"<pre><code>\"+(n?i:w(i,!0))+`</code></pre>\n`}blockquote({tokens:e}){return`<blockquote>\n${this.parser.parse(e)}</blockquote>\n`}html({text:e}){return e}def(e){return\"\"}heading({tokens:e,depth:t}){return`<h${t}>${this.parser.parseInline(e)}</h${t}>\n`}hr(e){return`<hr>\n`}list(e){let t=e.ordered,n=e.start,r=\"\";for(let o=0;o<e.items.length;o++){let a=e.items[o];r+=this.listitem(a)}let i=t?\"ol\":\"ul\",s=t&&n!==1?' start=\"'+n+'\"':\"\";return\"<\"+i+s+`>\n`+r+\"</\"+i+`>\n`}listitem(e){let t=\"\";if(e.task){let n=this.checkbox({checked:!!e.checked});e.loose?e.tokens[0]?.type===\"paragraph\"?(e.tokens[0].text=n+\" \"+e.tokens[0].text,e.tokens[0].tokens&&e.tokens[0].tokens.length>0&&e.tokens[0].tokens[0].type===\"text\"&&(e.tokens[0].tokens[0].text=n+\" \"+w(e.tokens[0].tokens[0].text),e.tokens[0].tokens[0].escaped=!0)):e.tokens.unshift({type:\"text\",raw:n+\" \",text:n+\" \",escaped:!0}):t+=n+\" \"}return t+=this.parser.parse(e.tokens,!!e.loose),`<li>${t}</li>\n`}checkbox({checked:e}){return\"<input \"+(e?'checked=\"\" ':\"\")+'disabled=\"\" type=\"checkbox\">'}paragraph({tokens:e}){return`<p>${this.parser.parseInline(e)}</p>\n`}table(e){let t=\"\",n=\"\";for(let i=0;i<e.header.length;i++)n+=this.tablecell(e.header[i]);t+=this.tablerow({text:n});let r=\"\";for(let i=0;i<e.rows.length;i++){let s=e.rows[i];n=\"\";for(let o=0;o<s.length;o++)n+=this.tablecell(s[o]);r+=this.tablerow({text:n})}return r&&(r=`<tbody>${r}</tbody>`),`<table>\n<thead>\n`+t+`</thead>\n`+r+`</table>\n`}tablerow({text:e}){return`<tr>\n${e}</tr>\n`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?\"th\":\"td\";return(e.align?`<${n} align=\"${e.align}\">`:`<${n}>`)+t+`</${n}>\n`}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${w(e,!0)}</code>`}br(e){return\"<br>\"}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=J(e);if(i===null)return r;e=i;let s='<a href=\"'+e+'\"';return t&&(s+=' title=\"'+w(t)+'\"'),s+=\">\"+r+\"</a>\",s}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=J(e);if(i===null)return w(n);e=i;let s=`<img src=\"${e}\" alt=\"${n}\"`;return t&&(s+=` title=\"${w(t)}\"`),s+=\">\",s}text(e){return\"tokens\"in e&&e.tokens?this.parser.parseInline(e.tokens):\"escaped\"in e&&e.escaped?e.text:w(e.text)}};var $=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return\"\"+e}image({text:e}){return\"\"+e}br(){return\"\"}};var R=class l{options;renderer;textRenderer;constructor(e){this.options=e||O,this.options.renderer=this.options.renderer||new P,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new $}static parse(e,t){return new l(t).parse(e)}static parseInline(e,t){return new l(t).parseInline(e)}parse(e,t=!0){let n=\"\";for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let o=i,a=this.options.extensions.renderers[o.type].call({parser:this},o);if(a!==!1||![\"space\",\"hr\",\"heading\",\"code\",\"table\",\"blockquote\",\"list\",\"html\",\"def\",\"paragraph\",\"text\"].includes(o.type)){n+=a||\"\";continue}}let s=i;switch(s.type){case\"space\":{n+=this.renderer.space(s);continue}case\"hr\":{n+=this.renderer.hr(s);continue}case\"heading\":{n+=this.renderer.heading(s);continue}case\"code\":{n+=this.renderer.code(s);continue}case\"table\":{n+=this.renderer.table(s);continue}case\"blockquote\":{n+=this.renderer.blockquote(s);continue}case\"list\":{n+=this.renderer.list(s);continue}case\"html\":{n+=this.renderer.html(s);continue}case\"def\":{n+=this.renderer.def(s);continue}case\"paragraph\":{n+=this.renderer.paragraph(s);continue}case\"text\":{let o=s,a=this.renderer.text(o);for(;r+1<e.length&&e[r+1].type===\"text\";)o=e[++r],a+=`\n`+this.renderer.text(o);t?n+=this.renderer.paragraph({type:\"paragraph\",raw:a,text:a,tokens:[{type:\"text\",raw:a,text:a,escaped:!0}]}):n+=a;continue}default:{let o='Token with \"'+s.type+'\" type was not found.';if(this.options.silent)return console.error(o),\"\";throw new Error(o)}}}return n}parseInline(e,t=this.renderer){let n=\"\";for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let o=this.options.extensions.renderers[i.type].call({parser:this},i);if(o!==!1||![\"escape\",\"html\",\"link\",\"image\",\"strong\",\"em\",\"codespan\",\"br\",\"del\",\"text\"].includes(i.type)){n+=o||\"\";continue}}let s=i;switch(s.type){case\"escape\":{n+=t.text(s);break}case\"html\":{n+=t.html(s);break}case\"link\":{n+=t.link(s);break}case\"image\":{n+=t.image(s);break}case\"strong\":{n+=t.strong(s);break}case\"em\":{n+=t.em(s);break}case\"codespan\":{n+=t.codespan(s);break}case\"br\":{n+=t.br(s);break}case\"del\":{n+=t.del(s);break}case\"text\":{n+=t.text(s);break}default:{let o='Token with \"'+s.type+'\" type was not found.';if(this.options.silent)return console.error(o),\"\";throw new Error(o)}}}return n}};var S=class{options;block;constructor(e){this.options=e||O}static passThroughHooks=new Set([\"preprocess\",\"postprocess\",\"processAllTokens\",\"emStrongMask\"]);static passThroughHooksRespectAsync=new Set([\"preprocess\",\"postprocess\",\"processAllTokens\"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(){return this.block?b.lex:b.lexInline}provideParser(){return this.block?R.parse:R.parseInline}};var B=class{defaults=L();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=R;Renderer=P;TextRenderer=$;Lexer=b;Tokenizer=y;Hooks=S;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case\"table\":{let i=r;for(let s of i.header)n=n.concat(this.walkTokens(s.tokens,t));for(let s of i.rows)for(let o of s)n=n.concat(this.walkTokens(o.tokens,t));break}case\"list\":{let i=r;n=n.concat(this.walkTokens(i.items,t));break}default:{let i=r;this.defaults.extensions?.childTokens?.[i.type]?this.defaults.extensions.childTokens[i.type].forEach(s=>{let o=i[s].flat(1/0);n=n.concat(this.walkTokens(o,t))}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let r={...n};if(r.async=this.defaults.async||r.async||!1,n.extensions&&(n.extensions.forEach(i=>{if(!i.name)throw new Error(\"extension name required\");if(\"renderer\"in i){let s=t.renderers[i.name];s?t.renderers[i.name]=function(...o){let a=i.renderer.apply(this,o);return a===!1&&(a=s.apply(this,o)),a}:t.renderers[i.name]=i.renderer}if(\"tokenizer\"in i){if(!i.level||i.level!==\"block\"&&i.level!==\"inline\")throw new Error(\"extension level must be 'block' or 'inline'\");let s=t[i.level];s?s.unshift(i.tokenizer):t[i.level]=[i.tokenizer],i.start&&(i.level===\"block\"?t.startBlock?t.startBlock.push(i.start):t.startBlock=[i.start]:i.level===\"inline\"&&(t.startInline?t.startInline.push(i.start):t.startInline=[i.start]))}\"childTokens\"in i&&i.childTokens&&(t.childTokens[i.name]=i.childTokens)}),r.extensions=t),n.renderer){let i=this.defaults.renderer||new P(this.defaults);for(let s in n.renderer){if(!(s in i))throw new Error(`renderer '${s}' does not exist`);if([\"options\",\"parser\"].includes(s))continue;let o=s,a=n.renderer[o],u=i[o];i[o]=(...p)=>{let c=a.apply(i,p);return c===!1&&(c=u.apply(i,p)),c||\"\"}}r.renderer=i}if(n.tokenizer){let i=this.defaults.tokenizer||new y(this.defaults);for(let s in n.tokenizer){if(!(s in i))throw new Error(`tokenizer '${s}' does not exist`);if([\"options\",\"rules\",\"lexer\"].includes(s))continue;let o=s,a=n.tokenizer[o],u=i[o];i[o]=(...p)=>{let c=a.apply(i,p);return c===!1&&(c=u.apply(i,p)),c}}r.tokenizer=i}if(n.hooks){let i=this.defaults.hooks||new S;for(let s in n.hooks){if(!(s in i))throw new Error(`hook '${s}' does not exist`);if([\"options\",\"block\"].includes(s))continue;let o=s,a=n.hooks[o],u=i[o];S.passThroughHooks.has(s)?i[o]=p=>{if(this.defaults.async&&S.passThroughHooksRespectAsync.has(s))return Promise.resolve(a.call(i,p)).then(f=>u.call(i,f));let c=a.call(i,p);return u.call(i,c)}:i[o]=(...p)=>{let c=a.apply(i,p);return c===!1&&(c=u.apply(i,p)),c}}r.hooks=i}if(n.walkTokens){let i=this.defaults.walkTokens,s=n.walkTokens;r.walkTokens=function(o){let a=[];return a.push(s.call(this,o)),i&&(a=a.concat(i.call(this,o))),a}}this.defaults={...this.defaults,...r}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return b.lex(e,t??this.defaults)}parser(e,t){return R.parse(e,t??this.defaults)}parseMarkdown(e){return(n,r)=>{let i={...r},s={...this.defaults,...i},o=this.onError(!!s.silent,!!s.async);if(this.defaults.async===!0&&i.async===!1)return o(new Error(\"marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.\"));if(typeof n>\"u\"||n===null)return o(new Error(\"marked(): input parameter is undefined or null\"));if(typeof n!=\"string\")return o(new Error(\"marked(): input parameter is of type \"+Object.prototype.toString.call(n)+\", string expected\"));s.hooks&&(s.hooks.options=s,s.hooks.block=e);let a=s.hooks?s.hooks.provideLexer():e?b.lex:b.lexInline,u=s.hooks?s.hooks.provideParser():e?R.parse:R.parseInline;if(s.async)return Promise.resolve(s.hooks?s.hooks.preprocess(n):n).then(p=>a(p,s)).then(p=>s.hooks?s.hooks.processAllTokens(p):p).then(p=>s.walkTokens?Promise.all(this.walkTokens(p,s.walkTokens)).then(()=>p):p).then(p=>u(p,s)).then(p=>s.hooks?s.hooks.postprocess(p):p).catch(o);try{s.hooks&&(n=s.hooks.preprocess(n));let p=a(n,s);s.hooks&&(p=s.hooks.processAllTokens(p)),s.walkTokens&&this.walkTokens(p,s.walkTokens);let c=u(p,s);return s.hooks&&(c=s.hooks.postprocess(c)),c}catch(p){return o(p)}}}onError(e,t){return n=>{if(n.message+=`\nPlease report this to https://github.com/markedjs/marked.`,e){let r=\"<p>An error occurred:</p><pre>\"+w(n.message+\"\",!0)+\"</pre>\";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}};var _=new B;function d(l,e){return _.parse(l,e)}d.options=d.setOptions=function(l){return _.setOptions(l),d.defaults=_.defaults,G(d.defaults),d};d.getDefaults=L;d.defaults=O;d.use=function(...l){return _.use(...l),d.defaults=_.defaults,G(d.defaults),d};d.walkTokens=function(l,e){return _.walkTokens(l,e)};d.parseInline=_.parseInline;d.Parser=R;d.parser=R.parse;d.Renderer=P;d.TextRenderer=$;d.Lexer=b;d.lexer=b.lex;d.Tokenizer=y;d.Hooks=S;d.parse=d;var Dt=d.options,Ht=d.setOptions,Zt=d.use,Gt=d.walkTokens,Nt=d.parseInline,jt=d,Ft=R.parse,Qt=b.lex;export{S as Hooks,b as Lexer,B as Marked,R as Parser,P as Renderer,$ as TextRenderer,y as Tokenizer,O as defaults,L as getDefaults,Qt as lexer,d as marked,Dt as options,jt as parse,Nt as parseInline,Ft as parser,Ht as setOptions,Zt as use,Gt as walkTokens};\n//# sourceMappingURL=marked.esm.js.map\n","export var SECONDS_A_MINUTE = 60;\nexport var SECONDS_A_HOUR = SECONDS_A_MINUTE * 60;\nexport var SECONDS_A_DAY = SECONDS_A_HOUR * 24;\nexport var SECONDS_A_WEEK = SECONDS_A_DAY * 7;\nexport var MILLISECONDS_A_SECOND = 1e3;\nexport var MILLISECONDS_A_MINUTE = SECONDS_A_MINUTE * MILLISECONDS_A_SECOND;\nexport var MILLISECONDS_A_HOUR = SECONDS_A_HOUR * MILLISECONDS_A_SECOND;\nexport var MILLISECONDS_A_DAY = SECONDS_A_DAY * MILLISECONDS_A_SECOND;\nexport var MILLISECONDS_A_WEEK = SECONDS_A_WEEK * MILLISECONDS_A_SECOND; // English locales\n\nexport var MS = 'millisecond';\nexport var S = 'second';\nexport var MIN = 'minute';\nexport var H = 'hour';\nexport var D = 'day';\nexport var W = 'week';\nexport var M = 'month';\nexport var Q = 'quarter';\nexport var Y = 'year';\nexport var DATE = 'date';\nexport var FORMAT_DEFAULT = 'YYYY-MM-DDTHH:mm:ssZ';\nexport var INVALID_DATE_STRING = 'Invalid Date'; // regex\n\nexport var REGEX_PARSE = /^(\\d{4})[-/]?(\\d{1,2})?[-/]?(\\d{0,2})[Tt\\s]*(\\d{1,2})?:?(\\d{1,2})?:?(\\d{1,2})?[.:]?(\\d+)?$/;\nexport var REGEX_FORMAT = /\\[([^\\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g;","// English [en]\n// We don't need weekdaysShort, weekdaysMin, monthsShort in en.js locale\nexport default {\n  name: 'en',\n  weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n  months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n  ordinal: function ordinal(n) {\n    var s = ['th', 'st', 'nd', 'rd'];\n    var v = n % 100;\n    return \"[\" + n + (s[(v - 20) % 10] || s[v] || s[0]) + \"]\";\n  }\n};","import * as C from './constant';\n\nvar padStart = function padStart(string, length, pad) {\n  var s = String(string);\n  if (!s || s.length >= length) return string;\n  return \"\" + Array(length + 1 - s.length).join(pad) + string;\n};\n\nvar padZoneStr = function padZoneStr(instance) {\n  var negMinutes = -instance.utcOffset();\n  var minutes = Math.abs(negMinutes);\n  var hourOffset = Math.floor(minutes / 60);\n  var minuteOffset = minutes % 60;\n  return \"\" + (negMinutes <= 0 ? '+' : '-') + padStart(hourOffset, 2, '0') + \":\" + padStart(minuteOffset, 2, '0');\n};\n\nvar monthDiff = function monthDiff(a, b) {\n  // function from moment.js in order to keep the same result\n  if (a.date() < b.date()) return -monthDiff(b, a);\n  var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month());\n  var anchor = a.clone().add(wholeMonthDiff, C.M);\n  var c = b - anchor < 0;\n  var anchor2 = a.clone().add(wholeMonthDiff + (c ? -1 : 1), C.M);\n  return +(-(wholeMonthDiff + (b - anchor) / (c ? anchor - anchor2 : anchor2 - anchor)) || 0);\n};\n\nvar absFloor = function absFloor(n) {\n  return n < 0 ? Math.ceil(n) || 0 : Math.floor(n);\n};\n\nvar prettyUnit = function prettyUnit(u) {\n  var special = {\n    M: C.M,\n    y: C.Y,\n    w: C.W,\n    d: C.D,\n    D: C.DATE,\n    h: C.H,\n    m: C.MIN,\n    s: C.S,\n    ms: C.MS,\n    Q: C.Q\n  };\n  return special[u] || String(u || '').toLowerCase().replace(/s$/, '');\n};\n\nvar isUndefined = function isUndefined(s) {\n  return s === undefined;\n};\n\nexport default {\n  s: padStart,\n  z: padZoneStr,\n  m: monthDiff,\n  a: absFloor,\n  p: prettyUnit,\n  u: isUndefined\n};","import * as C from './constant';\nimport en from './locale/en';\nimport U from './utils';\nvar L = 'en'; // global locale\n\nvar Ls = {}; // global loaded locale\n\nLs[L] = en;\nvar IS_DAYJS = '$isDayjsObject'; // eslint-disable-next-line no-use-before-define\n\nvar isDayjs = function isDayjs(d) {\n  return d instanceof Dayjs || !!(d && d[IS_DAYJS]);\n};\n\nvar parseLocale = function parseLocale(preset, object, isLocal) {\n  var l;\n  if (!preset) return L;\n\n  if (typeof preset === 'string') {\n    var presetLower = preset.toLowerCase();\n\n    if (Ls[presetLower]) {\n      l = presetLower;\n    }\n\n    if (object) {\n      Ls[presetLower] = object;\n      l = presetLower;\n    }\n\n    var presetSplit = preset.split('-');\n\n    if (!l && presetSplit.length > 1) {\n      return parseLocale(presetSplit[0]);\n    }\n  } else {\n    var name = preset.name;\n    Ls[name] = preset;\n    l = name;\n  }\n\n  if (!isLocal && l) L = l;\n  return l || !isLocal && L;\n};\n\nvar dayjs = function dayjs(date, c) {\n  if (isDayjs(date)) {\n    return date.clone();\n  } // eslint-disable-next-line no-nested-ternary\n\n\n  var cfg = typeof c === 'object' ? c : {};\n  cfg.date = date;\n  cfg.args = arguments; // eslint-disable-line prefer-rest-params\n\n  return new Dayjs(cfg); // eslint-disable-line no-use-before-define\n};\n\nvar wrapper = function wrapper(date, instance) {\n  return dayjs(date, {\n    locale: instance.$L,\n    utc: instance.$u,\n    x: instance.$x,\n    $offset: instance.$offset // todo: refactor; do not use this.$offset in you code\n\n  });\n};\n\nvar Utils = U; // for plugin use\n\nUtils.l = parseLocale;\nUtils.i = isDayjs;\nUtils.w = wrapper;\n\nvar parseDate = function parseDate(cfg) {\n  var date = cfg.date,\n      utc = cfg.utc;\n  if (date === null) return new Date(NaN); // null is invalid\n\n  if (Utils.u(date)) return new Date(); // today\n\n  if (date instanceof Date) return new Date(date);\n\n  if (typeof date === 'string' && !/Z$/i.test(date)) {\n    var d = date.match(C.REGEX_PARSE);\n\n    if (d) {\n      var m = d[2] - 1 || 0;\n      var ms = (d[7] || '0').substring(0, 3);\n\n      if (utc) {\n        return new Date(Date.UTC(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms));\n      }\n\n      return new Date(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms);\n    }\n  }\n\n  return new Date(date); // everything else\n};\n\nvar Dayjs = /*#__PURE__*/function () {\n  function Dayjs(cfg) {\n    this.$L = parseLocale(cfg.locale, null, true);\n    this.parse(cfg); // for plugin\n\n    this.$x = this.$x || cfg.x || {};\n    this[IS_DAYJS] = true;\n  }\n\n  var _proto = Dayjs.prototype;\n\n  _proto.parse = function parse(cfg) {\n    this.$d = parseDate(cfg);\n    this.init();\n  };\n\n  _proto.init = function init() {\n    var $d = this.$d;\n    this.$y = $d.getFullYear();\n    this.$M = $d.getMonth();\n    this.$D = $d.getDate();\n    this.$W = $d.getDay();\n    this.$H = $d.getHours();\n    this.$m = $d.getMinutes();\n    this.$s = $d.getSeconds();\n    this.$ms = $d.getMilliseconds();\n  } // eslint-disable-next-line class-methods-use-this\n  ;\n\n  _proto.$utils = function $utils() {\n    return Utils;\n  };\n\n  _proto.isValid = function isValid() {\n    return !(this.$d.toString() === C.INVALID_DATE_STRING);\n  };\n\n  _proto.isSame = function isSame(that, units) {\n    var other = dayjs(that);\n    return this.startOf(units) <= other && other <= this.endOf(units);\n  };\n\n  _proto.isAfter = function isAfter(that, units) {\n    return dayjs(that) < this.startOf(units);\n  };\n\n  _proto.isBefore = function isBefore(that, units) {\n    return this.endOf(units) < dayjs(that);\n  };\n\n  _proto.$g = function $g(input, get, set) {\n    if (Utils.u(input)) return this[get];\n    return this.set(set, input);\n  };\n\n  _proto.unix = function unix() {\n    return Math.floor(this.valueOf() / 1000);\n  };\n\n  _proto.valueOf = function valueOf() {\n    // timezone(hour) * 60 * 60 * 1000 => ms\n    return this.$d.getTime();\n  };\n\n  _proto.startOf = function startOf(units, _startOf) {\n    var _this = this;\n\n    // startOf -> endOf\n    var isStartOf = !Utils.u(_startOf) ? _startOf : true;\n    var unit = Utils.p(units);\n\n    var instanceFactory = function instanceFactory(d, m) {\n      var ins = Utils.w(_this.$u ? Date.UTC(_this.$y, m, d) : new Date(_this.$y, m, d), _this);\n      return isStartOf ? ins : ins.endOf(C.D);\n    };\n\n    var instanceFactorySet = function instanceFactorySet(method, slice) {\n      var argumentStart = [0, 0, 0, 0];\n      var argumentEnd = [23, 59, 59, 999];\n      return Utils.w(_this.toDate()[method].apply( // eslint-disable-line prefer-spread\n      _this.toDate('s'), (isStartOf ? argumentStart : argumentEnd).slice(slice)), _this);\n    };\n\n    var $W = this.$W,\n        $M = this.$M,\n        $D = this.$D;\n    var utcPad = \"set\" + (this.$u ? 'UTC' : '');\n\n    switch (unit) {\n      case C.Y:\n        return isStartOf ? instanceFactory(1, 0) : instanceFactory(31, 11);\n\n      case C.M:\n        return isStartOf ? instanceFactory(1, $M) : instanceFactory(0, $M + 1);\n\n      case C.W:\n        {\n          var weekStart = this.$locale().weekStart || 0;\n          var gap = ($W < weekStart ? $W + 7 : $W) - weekStart;\n          return instanceFactory(isStartOf ? $D - gap : $D + (6 - gap), $M);\n        }\n\n      case C.D:\n      case C.DATE:\n        return instanceFactorySet(utcPad + \"Hours\", 0);\n\n      case C.H:\n        return instanceFactorySet(utcPad + \"Minutes\", 1);\n\n      case C.MIN:\n        return instanceFactorySet(utcPad + \"Seconds\", 2);\n\n      case C.S:\n        return instanceFactorySet(utcPad + \"Milliseconds\", 3);\n\n      default:\n        return this.clone();\n    }\n  };\n\n  _proto.endOf = function endOf(arg) {\n    return this.startOf(arg, false);\n  };\n\n  _proto.$set = function $set(units, _int) {\n    var _C$D$C$DATE$C$M$C$Y$C;\n\n    // private set\n    var unit = Utils.p(units);\n    var utcPad = \"set\" + (this.$u ? 'UTC' : '');\n    var name = (_C$D$C$DATE$C$M$C$Y$C = {}, _C$D$C$DATE$C$M$C$Y$C[C.D] = utcPad + \"Date\", _C$D$C$DATE$C$M$C$Y$C[C.DATE] = utcPad + \"Date\", _C$D$C$DATE$C$M$C$Y$C[C.M] = utcPad + \"Month\", _C$D$C$DATE$C$M$C$Y$C[C.Y] = utcPad + \"FullYear\", _C$D$C$DATE$C$M$C$Y$C[C.H] = utcPad + \"Hours\", _C$D$C$DATE$C$M$C$Y$C[C.MIN] = utcPad + \"Minutes\", _C$D$C$DATE$C$M$C$Y$C[C.S] = utcPad + \"Seconds\", _C$D$C$DATE$C$M$C$Y$C[C.MS] = utcPad + \"Milliseconds\", _C$D$C$DATE$C$M$C$Y$C)[unit];\n    var arg = unit === C.D ? this.$D + (_int - this.$W) : _int;\n\n    if (unit === C.M || unit === C.Y) {\n      // clone is for badMutable plugin\n      var date = this.clone().set(C.DATE, 1);\n      date.$d[name](arg);\n      date.init();\n      this.$d = date.set(C.DATE, Math.min(this.$D, date.daysInMonth())).$d;\n    } else if (name) this.$d[name](arg);\n\n    this.init();\n    return this;\n  };\n\n  _proto.set = function set(string, _int2) {\n    return this.clone().$set(string, _int2);\n  };\n\n  _proto.get = function get(unit) {\n    return this[Utils.p(unit)]();\n  };\n\n  _proto.add = function add(number, units) {\n    var _this2 = this,\n        _C$MIN$C$H$C$S$unit;\n\n    number = Number(number); // eslint-disable-line no-param-reassign\n\n    var unit = Utils.p(units);\n\n    var instanceFactorySet = function instanceFactorySet(n) {\n      var d = dayjs(_this2);\n      return Utils.w(d.date(d.date() + Math.round(n * number)), _this2);\n    };\n\n    if (unit === C.M) {\n      return this.set(C.M, this.$M + number);\n    }\n\n    if (unit === C.Y) {\n      return this.set(C.Y, this.$y + number);\n    }\n\n    if (unit === C.D) {\n      return instanceFactorySet(1);\n    }\n\n    if (unit === C.W) {\n      return instanceFactorySet(7);\n    }\n\n    var step = (_C$MIN$C$H$C$S$unit = {}, _C$MIN$C$H$C$S$unit[C.MIN] = C.MILLISECONDS_A_MINUTE, _C$MIN$C$H$C$S$unit[C.H] = C.MILLISECONDS_A_HOUR, _C$MIN$C$H$C$S$unit[C.S] = C.MILLISECONDS_A_SECOND, _C$MIN$C$H$C$S$unit)[unit] || 1; // ms\n\n    var nextTimeStamp = this.$d.getTime() + number * step;\n    return Utils.w(nextTimeStamp, this);\n  };\n\n  _proto.subtract = function subtract(number, string) {\n    return this.add(number * -1, string);\n  };\n\n  _proto.format = function format(formatStr) {\n    var _this3 = this;\n\n    var locale = this.$locale();\n    if (!this.isValid()) return locale.invalidDate || C.INVALID_DATE_STRING;\n    var str = formatStr || C.FORMAT_DEFAULT;\n    var zoneStr = Utils.z(this);\n    var $H = this.$H,\n        $m = this.$m,\n        $M = this.$M;\n    var weekdays = locale.weekdays,\n        months = locale.months,\n        meridiem = locale.meridiem;\n\n    var getShort = function getShort(arr, index, full, length) {\n      return arr && (arr[index] || arr(_this3, str)) || full[index].slice(0, length);\n    };\n\n    var get$H = function get$H(num) {\n      return Utils.s($H % 12 || 12, num, '0');\n    };\n\n    var meridiemFunc = meridiem || function (hour, minute, isLowercase) {\n      var m = hour < 12 ? 'AM' : 'PM';\n      return isLowercase ? m.toLowerCase() : m;\n    };\n\n    var matches = function matches(match) {\n      switch (match) {\n        case 'YY':\n          return String(_this3.$y).slice(-2);\n\n        case 'YYYY':\n          return Utils.s(_this3.$y, 4, '0');\n\n        case 'M':\n          return $M + 1;\n\n        case 'MM':\n          return Utils.s($M + 1, 2, '0');\n\n        case 'MMM':\n          return getShort(locale.monthsShort, $M, months, 3);\n\n        case 'MMMM':\n          return getShort(months, $M);\n\n        case 'D':\n          return _this3.$D;\n\n        case 'DD':\n          return Utils.s(_this3.$D, 2, '0');\n\n        case 'd':\n          return String(_this3.$W);\n\n        case 'dd':\n          return getShort(locale.weekdaysMin, _this3.$W, weekdays, 2);\n\n        case 'ddd':\n          return getShort(locale.weekdaysShort, _this3.$W, weekdays, 3);\n\n        case 'dddd':\n          return weekdays[_this3.$W];\n\n        case 'H':\n          return String($H);\n\n        case 'HH':\n          return Utils.s($H, 2, '0');\n\n        case 'h':\n          return get$H(1);\n\n        case 'hh':\n          return get$H(2);\n\n        case 'a':\n          return meridiemFunc($H, $m, true);\n\n        case 'A':\n          return meridiemFunc($H, $m, false);\n\n        case 'm':\n          return String($m);\n\n        case 'mm':\n          return Utils.s($m, 2, '0');\n\n        case 's':\n          return String(_this3.$s);\n\n        case 'ss':\n          return Utils.s(_this3.$s, 2, '0');\n\n        case 'SSS':\n          return Utils.s(_this3.$ms, 3, '0');\n\n        case 'Z':\n          return zoneStr;\n        // 'ZZ' logic below\n\n        default:\n          break;\n      }\n\n      return null;\n    };\n\n    return str.replace(C.REGEX_FORMAT, function (match, $1) {\n      return $1 || matches(match) || zoneStr.replace(':', '');\n    }); // 'ZZ'\n  };\n\n  _proto.utcOffset = function utcOffset() {\n    // Because a bug at FF24, we're rounding the timezone offset around 15 minutes\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(this.$d.getTimezoneOffset() / 15) * 15;\n  };\n\n  _proto.diff = function diff(input, units, _float) {\n    var _this4 = this;\n\n    var unit = Utils.p(units);\n    var that = dayjs(input);\n    var zoneDelta = (that.utcOffset() - this.utcOffset()) * C.MILLISECONDS_A_MINUTE;\n    var diff = this - that;\n\n    var getMonth = function getMonth() {\n      return Utils.m(_this4, that);\n    };\n\n    var result;\n\n    switch (unit) {\n      case C.Y:\n        result = getMonth() / 12;\n        break;\n\n      case C.M:\n        result = getMonth();\n        break;\n\n      case C.Q:\n        result = getMonth() / 3;\n        break;\n\n      case C.W:\n        result = (diff - zoneDelta) / C.MILLISECONDS_A_WEEK;\n        break;\n\n      case C.D:\n        result = (diff - zoneDelta) / C.MILLISECONDS_A_DAY;\n        break;\n\n      case C.H:\n        result = diff / C.MILLISECONDS_A_HOUR;\n        break;\n\n      case C.MIN:\n        result = diff / C.MILLISECONDS_A_MINUTE;\n        break;\n\n      case C.S:\n        result = diff / C.MILLISECONDS_A_SECOND;\n        break;\n\n      default:\n        result = diff; // milliseconds\n\n        break;\n    }\n\n    return _float ? result : Utils.a(result);\n  };\n\n  _proto.daysInMonth = function daysInMonth() {\n    return this.endOf(C.M).$D;\n  };\n\n  _proto.$locale = function $locale() {\n    // get locale object\n    return Ls[this.$L];\n  };\n\n  _proto.locale = function locale(preset, object) {\n    if (!preset) return this.$L;\n    var that = this.clone();\n    var nextLocaleName = parseLocale(preset, object, true);\n    if (nextLocaleName) that.$L = nextLocaleName;\n    return that;\n  };\n\n  _proto.clone = function clone() {\n    return Utils.w(this.$d, this);\n  };\n\n  _proto.toDate = function toDate() {\n    return new Date(this.valueOf());\n  };\n\n  _proto.toJSON = function toJSON() {\n    return this.isValid() ? this.toISOString() : null;\n  };\n\n  _proto.toISOString = function toISOString() {\n    // ie 8 return\n    // new Dayjs(this.valueOf() + this.$d.getTimezoneOffset() * 60000)\n    // .format('YYYY-MM-DDTHH:mm:ss.SSS[Z]')\n    return this.$d.toISOString();\n  };\n\n  _proto.toString = function toString() {\n    return this.$d.toUTCString();\n  };\n\n  return Dayjs;\n}();\n\nvar proto = Dayjs.prototype;\ndayjs.prototype = proto;\n[['$ms', C.MS], ['$s', C.S], ['$m', C.MIN], ['$H', C.H], ['$W', C.D], ['$M', C.M], ['$y', C.Y], ['$D', C.DATE]].forEach(function (g) {\n  proto[g[1]] = function (input) {\n    return this.$g(input, g[0], g[1]);\n  };\n});\n\ndayjs.extend = function (plugin, option) {\n  if (!plugin.$i) {\n    // install plugin only once\n    plugin(option, Dayjs, dayjs);\n    plugin.$i = true;\n  }\n\n  return dayjs;\n};\n\ndayjs.locale = parseLocale;\ndayjs.isDayjs = isDayjs;\n\ndayjs.unix = function (timestamp) {\n  return dayjs(timestamp * 1e3);\n};\n\ndayjs.en = Ls[L];\ndayjs.Ls = Ls;\ndayjs.p = {};\nexport default dayjs;","import { marked } from \"marked\"\nimport { LitElement, html, css } from \"lit\"\nimport { customElement, property } from \"lit/decorators.js\"\nimport type { NewsData, ProcessedNewsItem } from \"../../types/news-feed\"\nimport { Task } from \"@lit/task\"\nimport { sanitizeHtml } from \"../../utils/html\"\nimport dayjs from \"dayjs/esm\"\n\n/**\n * `news-feed` - A web component that displays news items from a JSON feed.\n *\n * @customElement\n * @lit-element\n * @example\n * <news-feed\n *   url=\"https://raw.githubusercontent.com/openfoodfacts/smooth-app_assets/refs/heads/main/prod/tagline/android/main.json\"\n *   language-code=\"en\"\n *   country-code=\"fr\"\n *   app-version=\"3.5.0\"\n * ></news-feed>\n */\n@customElement(\"news-feed\")\nexport class NewsFeed extends LitElement {\n  @property({ attribute: \"url\" }) url?: string\n  @property({ attribute: \"lang\" }) languageCode?: string\n  @property({ attribute: \"country\" }) countryCode?: string\n  @property({ attribute: \"app-version\" }) appVersion?: string\n\n  static override styles = css`\n    :host {\n      display: block;\n      font-family: \"Inter\", sans-serif;\n      width: 100%;\n      margin: 1rem auto;\n      border: 1px solid #e2e8f0;\n      border-radius: 0.5rem;\n      box-shadow:\n        0 1px 3px 0 rgba(0, 0, 0, 0.1),\n        0 1px 2px 0 rgba(0, 0, 0, 0.06);\n      overflow: hidden;\n      background: #fff;\n    }\n\n    .loading-container {\n      padding: 1rem;\n      text-align: center;\n      color: #6b7280;\n    }\n\n    .error-container {\n      padding: 1rem;\n      text-align: center;\n      color: #ef4444;\n      background-color: #fee2e2;\n      border-radius: 0.375rem;\n    }\n\n    .news-container {\n      border-top: 1px solid #e5e7eb;\n    }\n\n    .news-item-wrapper {\n      transition: background-color 0.2s ease-in-out;\n      display: block;\n      text-decoration: none;\n      color: inherit;\n      border-bottom: 1px solid #e5e7eb;\n    }\n\n    .news-item-wrapper:last-child {\n      border-bottom: none;\n    }\n\n    .news-item-wrapper:hover {\n      background-color: #f9fafb;\n    }\n\n    .news-item {\n      display: flex;\n      align-items: flex-start;\n      padding: 1rem;\n    }\n\n    .icon {\n      width: 2.5rem;\n      height: 2.5rem;\n      object-fit: contain;\n      margin-right: 0.75rem;\n      border-radius: 0.375rem;\n      flex-shrink: 0;\n    }\n\n    .placeholder-icon {\n      width: 2.5rem;\n      height: 2.5rem;\n      background-color: #e5e7eb;\n      border-radius: 0.375rem;\n      margin-right: 0.75rem;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      color: #9ca3af;\n      font-size: 0.75rem;\n      flex-shrink: 0;\n      text-transform: uppercase;\n    }\n\n    .content {\n      flex: 1;\n      min-width: 0;\n    }\n\n    .title {\n      font-weight: 600;\n      color: #1f2937;\n      margin-bottom: 0.25rem;\n      margin-top: 0;\n    }\n\n    .message {\n      font-size: 0.875rem;\n      color: #4b5563;\n      line-height: 1.4;\n      margin: 0;\n    }\n\n    .message strong,\n    .message b {\n      font-weight: 600;\n      color: #1f2937;\n    }\n\n    /* Message Type Styles */\n    .info {\n      border-left: 4px solid #3b82f6; /* Blue */\n    }\n\n    .warning {\n      border-left: 4px solid #f59e0b; /* Amber */\n    }\n\n    .error {\n      border-left: 4px solid #ef4444; /* Red */\n    }\n\n    .no-news {\n      padding: 1rem;\n      text-align: center;\n      color: #6b7280;\n    }\n\n    /* --- Dark Mode --- */\n    @media (prefers-color-scheme: dark) {\n      :host {\n        background: #18181b;\n        border-color: #27272a;\n        box-shadow:\n          0 1px 3px 0 rgba(0, 0, 0, 0.4),\n          0 1px 2px 0 rgba(0, 0, 0, 0.3);\n      }\n      .loading-container,\n      .no-news {\n        color: #a1a1aa;\n      }\n      .error-container {\n        color: #f87171;\n        background-color: #7f1d1d;\n      }\n      .news-container {\n        border-top: 1px solid #27272a;\n      }\n      .news-item-wrapper {\n        border-bottom: 1px solid #27272a;\n      }\n      .news-item-wrapper:hover {\n        background-color: #27272a;\n      }\n      .news-item {\n        background: transparent;\n      }\n      .icon {\n        background: white;\n      }\n      .placeholder-icon {\n        background-color: #27272a;\n        color: #a1a1aa;\n      }\n      .title {\n        color: #fafafa;\n      }\n      .message {\n        color: #d4d4d8;\n      }\n      .message strong,\n      .message b {\n        color: #fafafa;\n      }\n      .info {\n        border-left: 4px solid #2563eb;\n      }\n      .warning {\n        border-left: 4px solid #fbbf24;\n      }\n      .error {\n        border-left: 4px solid #f87171;\n      }\n    }\n  `\n\n  // --- Helper Methods ---\n\n  private getLang(lang: string | undefined) {\n    return lang || navigator.language?.split(\"-\")[0] || \"en\"\n  }\n\n  private getFullLang(lang: string | undefined) {\n    // Get the full language code if available (e.g., 'fr-FR')\n    return lang || navigator.language || \"en\"\n  }\n\n  /**\n   * Go from raw data to data that can be displayed\n   */\n  private processNewsData(\n    rawData: NewsData,\n    { lang: currentLang, fullLang: currentFullLang }: { lang: string; fullLang: string }\n  ): ProcessedNewsItem[] {\n    const processedItems = []\n    const newsDetailsMap = rawData.news || {}\n    const feedIds = rawData.tagline_feed?.default?.news || [] // Safely access nested properties\n\n    if (!rawData.news) {\n      console.warn(\"[NewsFeed] 'news' object missing in raw data.\")\n      return []\n    }\n\n    if (!rawData.tagline_feed?.default?.news) {\n      console.warn(\"[NewsFeed] 'tagline_feed.default.news' array missing in raw data.\")\n      return []\n    }\n\n    for (const feedItem of feedIds) {\n      const id = feedItem.id\n      const details = newsDetailsMap[id]\n\n      if (!details) {\n        console.warn(`[NewsFeed] Details not found for news ID: ${id}`)\n        continue // Skip if details are missing for this ID\n      }\n\n      // --- Translation Selection ---\n      let translation = details.translations?.default || {} // Start with default\n      // Check for exact full language match (e.g., fr_FR) - adjust key format if needed\n      const fullLangKey = currentFullLang.replace(\"-\", \"_\") // e.g., en-US -> en_US\n      if (details.translations && details.translations[fullLangKey]) {\n        translation = details.translations[fullLangKey]\n      }\n      // Else, check for primary language match (e.g., fr)\n      else if (details.translations && details.translations[currentLang]) {\n        translation = details.translations[currentLang]\n      }\n\n      // --- Create Processed Item ---\n      // Ensure we have fallbacks if translation or default is incomplete\n      const defaultTranslation = details.translations?.default || {}\n\n      processedItems.push({\n        id: id, // Keep the original ID\n        title: translation.title || defaultTranslation.title || \"\", // Fallback chain\n        message: translation.message || defaultTranslation.message || \"\", // Fallback chain\n        // Use the URL from the translation first, then the main item URL\n        url: translation.url || details.url || \"\",\n        // Use the image URL from the translation's image object\n        icon_url: translation.image?.url || defaultTranslation.image?.url || \"\",\n        // Copy other relevant properties directly from details\n        start_date: details.start_date,\n        end_date: details.end_date,\n        languages: details.languages, // Keep original filters if needed\n        countries: details.countries, // Keep original filters if needed\n        min_app_version: details.min_app_version,\n        max_app_version: details.max_app_version,\n        enabled: details.enabled !== false, // Default to true if not explicitly false\n        message_type: (details.message_type || \"info\").toLowerCase(), // Default to 'info'\n        // Add other fields from 'details' if needed for filtering later\n      })\n    }\n\n    return processedItems\n  }\n\n  private versionCompare(v1: string | undefined, v2: string | undefined) {\n    const parts1 = (v1 || \"\").split(/[.-]/)\n    const parts2 = (v2 || \"\").split(/[.-]/)\n    for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n      const p1Str = parts1[i] || \"0\"\n      const p2Str = parts2[i] || \"0\"\n      const p1Num = parseInt(p1Str, 10)\n      const p2Num = parseInt(p2Str, 10)\n      if (!isNaN(p1Num) && !isNaN(p2Num)) {\n        if (p1Num > p2Num) return 1\n        if (p1Num < p2Num) return -1\n      } else {\n        if (p1Str > p2Str) return 1\n        if (p1Str < p2Str) return -1\n      }\n    }\n    return 0\n  }\n\n  // --- Filtering Logic ---\n  private filterNews(\n    processedNewsItems: ProcessedNewsItem[],\n    {\n      lang: currentLang,\n      country: currentCountry,\n      appVersion: currentAppVersion,\n    }: { lang: string; country?: string; appVersion?: string }\n  ): ProcessedNewsItem[] {\n    const now = dayjs()\n\n    return processedNewsItems.filter((item) => {\n      // 1. Check if explicitly disabled (already handled in processing, but double check)\n      if (item.enabled === false) {\n        return false\n      }\n\n      // 2. Check dates (using processed item properties)\n      // Ensure date strings are valid before creating Date objects\n      const startDate = dayjs(item.start_date).isValid() ? dayjs(item.start_date) : null\n      const endDate = dayjs(item.end_date).isValid() ? dayjs(item.end_date) : null\n\n      if ((startDate && now.isBefore(startDate)) || (endDate && now.isAfter(endDate))) {\n        return false // Not started yet or already ended\n      }\n\n      // 3. Check language (using original 'languages' array if present on item)\n      if (item.languages && item.languages.length > 0) {\n        const langMatch = item.languages.some(\n          (lang) =>\n            currentLang.toLowerCase() === lang.toLowerCase() ||\n            currentLang.startsWith(lang.toLowerCase() + \"-\")\n        )\n        if (!langMatch) {\n          return false\n        }\n      }\n\n      // 4. Check country (using original 'countries' array if present on item)\n      if (currentCountry && item.countries && item.countries.length > 0) {\n        const countryMatch = item.countries.some(\n          (country) => currentCountry.toLowerCase() === country.toLowerCase()\n        )\n\n        if (!countryMatch) {\n          return false\n        }\n      }\n\n      // 5. Check App Version (using min/max versions from item)\n      if (currentAppVersion) {\n        if (\n          item.min_app_version &&\n          this.versionCompare(currentAppVersion, item.min_app_version) < 0\n        ) {\n          return false\n        }\n        if (\n          item.max_app_version &&\n          this.versionCompare(currentAppVersion, item.max_app_version) > 0\n        ) {\n          return false\n        }\n      }\n\n      // If all checks pass\n      return true\n    })\n  }\n\n  private _newsTask = new Task(this, {\n    args: () => [this.url, this.languageCode, this.countryCode, this.appVersion],\n    task: async ([url, lang, country, appVersion]) => {\n      if (!url) {\n        throw new Error(\"No data URL provided.\")\n      }\n\n      const response = await fetch(url)\n\n      if (!response.ok) {\n        throw new Error(`HTTP error! status: ${response.status}`)\n      }\n\n      const currentLang = this.getLang(lang)\n      const currentFullLang = this.getFullLang(lang)\n\n      const rawData = (await response.json()) as NewsData\n      const items = this.processNewsData(rawData, { lang: currentLang, fullLang: currentFullLang })\n\n      const filteredItems = this.filterNews(items, {\n        lang: currentLang,\n        country: country,\n        appVersion: appVersion,\n      })\n\n      const parsedNews = Promise.all(\n        filteredItems.map(async (item) => ({\n          ...item,\n          parsedMessage: item.message ? await marked.parse(item.message) : \"\",\n        }))\n      )\n\n      return parsedNews\n    },\n  })\n\n  // --- Lit Render Methods ---\n\n  _renderNewsItem(item: ProcessedNewsItem & { parsedMessage: string }) {\n    const hasUrl = item.url && item.url.trim() !== \"\"\n    const placeholderId = `placeholder-${item.id || Math.random().toString(36).substring(7)}`\n\n    // Create placeholder icon content\n    const placeholderContent = item.id ? item.id.substring(0, 3) : \"NWS\"\n\n    // Create the icon html - either image with fallback or just placeholder\n    const iconTemplate = item.icon_url\n      ? html`\n          <img\n            src=${item.icon_url}\n            alt=\"\"\n            class=\"icon\"\n            @error=${(e: Event) => {\n              const target = e.target as HTMLImageElement\n              target.style.display = \"none\"\n\n              const element = this.shadowRoot!.querySelector(`#${placeholderId}`)! as HTMLElement\n              element.style.display = \"flex\"\n            }}\n          />\n          <div id=${placeholderId} class=\"placeholder-icon\" style=\"display: none;\">\n            ${placeholderContent}\n          </div>\n        `\n      : html`<div id=${placeholderId} class=\"placeholder-icon\">${placeholderContent}</div>`\n\n    // Content template - always the same\n    const contentTemplate = html`\n      <div class=\"content\">\n        ${item.title ? html`<h3 class=\"title\">${item.title}</h3>` : \"\"}\n        <p class=\"message\">\n          ${sanitizeHtml(item.parsedMessage) || item.message || \"No message content.\"}\n        </p>\n      </div>\n    `\n\n    if (!hasUrl) {\n      return html`\n        <div class=\"news-item-wrapper\" data-news-id=${item.id}>\n          <div class=\"news-item ${item.message_type}\">${iconTemplate} ${contentTemplate}</div>\n        </div>\n      `\n    }\n\n    return html`\n      <a\n        href=${item.url ?? \"\"}\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        class=\"news-item-wrapper\"\n        data-news-id=${item.id}\n      >\n        <div class=\"news-item ${item.message_type}\">${iconTemplate} ${contentTemplate}</div>\n      </a>\n    `\n  }\n\n  override render() {\n    return this._newsTask.render({\n      pending: () => html`<div class=\"loading-container\">Loading news...</div>`,\n      error: (e) => html`<div class=\"error-container\">${e}</div>`,\n      complete: (news) => {\n        return html`\n          <div class=\"news-container\">\n            ${news.length > 0\n              ? news.map((item) => this._renderNewsItem(item))\n              : html`<div class=\"no-news\">No relevant news available right now.</div>`}\n          </div>\n        `\n      },\n    })\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"news-feed\": NewsFeed\n  }\n}\n","export { setLocale, getLocale } from \"./localization\"\nexport { OffWebcomponentsConfiguration } from \"./components/shared/off-webcomponents-configuration\"\nexport { RobotoffQuestion } from \"./components/robotoff-question/robotoff-question\"\nexport { RobotoffNutrientExtraction } from \"./components/robotoff-nutrient-extraction/robotoff-nutrient-extraction\"\nexport { RobotoffIngredientSpellcheck } from \"./components/robotoff-ingredient-spellcheck/robotoff-ingredient-spellcheck\"\nexport { RobotoffContributionMessage } from \"./components/robotoff-contribution-message/robotoff-contribution-message\"\nexport { KnowledgePanelsComponent } from \"./components/knowledge-panels/knowledge-panels\"\nexport { DonationBanner } from \"./components/donation-banner/donation-banner\"\nexport { MobileBadges } from \"./components/mobile-badges/mobile-badges\"\nexport { DownloadAppQrCode } from \"./components/download-app-qr-code/download-app-qr-code\"\nexport { BarcodeScanner } from \"./components/barcode-scanner/barcode-scanner\"\nexport { DeleteModal } from \"./components/folksonomy/delete-modal\"\nexport { FolksonomyEditor } from \"./components/folksonomy/folksonomy-editor\"\nexport { FolksonomyProperties } from \"./components/folksonomy/folksonomy-properties\"\nexport { FolksonomyPropertyProducts } from \"./components/folksonomy/folksonomy-property-products\"\nexport { AutocompleteInput } from \"./components/shared/autocomplete-input\"\nexport { RobotoffIngredientDetection as RobotoffCrops } from \"./components/robotoff-ingredient-detection/robotoff-ingredient-detection\"\nexport { ProductCard } from \"./components/product-card/product-card\"\nexport { NewsFeed } from \"./components/news-feed/news-feed\"\n\n// Will be added in the future when design is ready\n// export { KnowledgePanelsComponent } from \"./components/knowledge-panels/knowledge-panels\"\n\ntype Global = typeof globalThis & {\n  OFF_WEBCOMPONENTS_VERSION?: string\n}\n\nif (window) {\n  ;(window as Global).OFF_WEBCOMPONENTS_VERSION = __OFF_WEBCOMPONENTS_VERSION__\n} else if (globalThis) {\n  ;(globalThis as Global).OFF_WEBCOMPONENTS_VERSION = __OFF_WEBCOMPONENTS_VERSION__\n}\n"],"names":["sourceLocale","targetLocales","__defProp","__defNormalProp","obj","key","value","__publicField","__accessCheck","member","msg","__privateIn","__privateAdd","__privateMethod","method","defaultEquals","a","b","activeConsumer","inNotificationPhase","epoch","SIGNAL","setActiveConsumer","consumer","prev","getActiveConsumer","isInNotificationPhase","REACTIVE_NODE","producerAccessed","node","idx","assertConsumerNode","consumerIsLive","staleProducer","producerRemoveLiveConsumerAtIndex","producerAddLiveConsumer","producerIncrementEpoch","producerUpdateValueVersion","consumerPollProducersForChange","producerNotifyConsumers","consumerMarkDirty","producerUpdatesAllowed","_a","consumerBeforeComputation","consumerAfterComputation","prevConsumer","i","producer","seenVersion","indexOfThis","assertProducerNode","lastIdx","idxProducer","computedGet","ERRORED","createComputed","computation","COMPUTED_NODE","computed","UNSET","COMPUTING","oldValue","newValue","wasEqual","err","defaultThrowError","throwInvalidWriteToSignalErrorFn","throwInvalidWriteToSignalError","createSignal","initialValue","SIGNAL_NODE","getter","signalGetFn","signalSetFn","signalValueChanged","NODE","Signal","Signal2","_brand","_b","_brand2","State","options","equals","ref","s","Computed","c","subtle2","_a2","_brand3","_assertSignals","assertSignals_fn","untrack","cb","output","prevActiveConsumer","introspectSources","sink","_a3","n","introspectSinks","signal","hasSinks","liveConsumerNode","hasSources","producerNode","Watcher","notify","signals","idxConsumer","w","currentComputed","h","e","t","i$2","f","o","r","l","DEFAULT_ROBOTOFF_CONFIGURATION","DEFAULT_FOLKSONOMY_CONFIGURATION","EventType","LoadingState","DEFAULT_LANGUAGE_CODE","DEFAULT_COUNTRY_CODE","EventState","DEFAULT_ASSETS_IMAGES_PATH","SELECT_ICON_FILE_NAME","WHITE_SELECT_ICON_FILE_NAME","RobotoffContributionType","STATIC_HOST","assetsImagesPath","getImageUrl","fileName","countryCode","languageCode","getLocale","setLocale","configureLocalization","locale","__variableDynamicImportRuntimeHelper","setLanguageCode","newLanguageCode","SignalObject","SignalMap","robotoffConfiguration","getRobotoffImageUrl","path","folksonomyConfiguration","userInfo","userInfoLoading","paramToString","isNullOrUndefined","item","paramsToUrl","params","acc","addParamsToUrl","url","setValueAndParentsObjectIfNotExists","keys","lastKey","lastObject","randomIdGenerator","initDebounce","callback","debounceTime","timeout","createDebounce","downloadCSV","rows","filename","headers","csvContent","row","blob","link","today","finalFilename","removeUselessZeros","triggerSubmit","form","normalizeRotation","rotation","OpenFoodFactsSlackLink","FolksnomyEngineDocumentationLink","FolksnomyEnginePropertyLink","getUrl","openfoodfactsApiUrl","fetchProduct","productCode","response","fetchNutrientsOrder","DEFAULT_OPENFOODFACTS_API_URL","nutrientsOrderPromises","nutrientsOrderByCountryCode","setOrderOfNutrient","index","nutrient","subNutrient","fetchNutrientsOrderByCountryCode","nutrientsOrderPromise","request","data","sortKeysByNutrientsOrder","nutrientsOrder","aIndex","bIndex","CONFIGURATION_PROPERTIES","configuration","OffWebcomponentsConfiguration","LitElement","name","oldval","newval","config","propertyName","__decorateClass","property","customElement","AnnotationAnswer","InsightAnnotationSize","InsightType","PATH_PARAM_RE","supportsRequestInitExt","randomID","createClient","clientOptions","baseUrl","CustomRequest","baseFetch","globalQuerySerializer","globalBodySerializer","baseHeaders","requestInitExt","baseOptions","removeTrailingSlash","middlewares","coreFetch","schemaPath","fetchOptions","localBaseUrl","fetch","Request","parseAs","requestQuerySerializer","bodySerializer","defaultBodySerializer","body","init","finalBaseUrl","querySerializer","createQuerySerializer","serializedBody","mergeHeaders","finalHeaders","requestInit","id","createFinalURL","m","result","error2","errorAfterMiddleware","error","middleware","serializePrimitiveParam","serializeObjectParam","values","joiner","k","final2","finalName","final","serializeArrayParam","joiner2","v","queryParams","search","defaultPathSerializer","pathname","pathParams","nextURL","match","explode","style","finalURL","allHeaders","iterator","v2","VERSION","USER_AGENT","BackendType","BACKEND_DOMAINS","BACKEND_NAMES","DEFAULT_ROBOTOFF_API_URL","formBody","Robotoff","code","query","logoId","TAXONOMY_URL","taxo","formData","entries","ProductOpenerApiV2","entry","barcode","photoId","ocrEngine","product","credentials","languageCodes","productNames","lang","productName","getProductNameInLang","ingredientsTexts","ingredientsText","getProductIngredientsInLang","imgid","cropData","imageFile","imagefield","angle","images","ProductOpenerApiV3","OpenFoodFacts","username","password","nullableCredentials","token","wrappedFetch","newAccessToken","parts","payload","brandName","languageName","facet","opts","createRobotoff","fetchWithCredentials","getApiUrl","annotate","apiUrl","robotoff","insightId","annotation","correction","questionRequestParams","requestParams","questionsById","questionIdsByProductCode","currentQuestionIndexByProductCode","isQuestionsFinishedByProductCode","questions","currentQuestionIndex","hasQuestions","numberOfQuestions","isQuestionsFinished","fetchQuestionsByProductCode","question","checkIfQuestionsFinishedByProductCode","current","count","answerQuestion","nextQuestionByProductCode","h$1","OffWcLoader","html","localized","DARKER_WHITE","LIGHT_BLACK","CHOCOLATE","CAPPUCINO","LIGHT_GREY","GREY","BLUE","SUCCESS","DANGER","LIGHT_RED","LIGHT_GREEN","GREEN","SAFE_DARKER_WHITE","unsafeCSS","SAFE_LIGHT_BLACK","SAFE_CHOCOLATE","SAFE_CAPPUCINO","SAFE_LIGHT_GREY","SAFE_GREY","SAFE_BLUE","SAFE_SUCCESS","SAFE_DANGER","SAFE_LIGHT_RED","SAFE_LIGHT_GREEN","SAFE_GREEN","ButtonType","getDefaultButtonClasses","css","BUTTON_CLASS_BY_TYPE","getButtonClasses","types","buttonClasses","type","DURATION","LoadingWithTimeoutMixin","superClass","initialLoading","LoadingWithTimeoutMixinClass","loading","timeElapsed","timeoutTime","resolve","state","RELATIVE","FLEX","IS_HIDDEN","FULL_WIDTH","LoadingSpin","LoadingButton","nothing","ZoomIcon","UnzoomIcon","ZoomUnzoomButton","RotateLeftIcon","RotateRightIcon","Breakpoints","mobileAndTabletRegex","mobileAndTabletCheck","IS_BROWSER","WINDOW","IS_TOUCH_DEVICE","HAS_POINTER_EVENT","NAMESPACE","CROPPER_CANVAS","CROPPER_CROSSHAIR","CROPPER_HANDLE","CROPPER_IMAGE","CROPPER_SELECTION","CROPPER_SHADE","ACTION_SELECT","ACTION_MOVE","ACTION_SCALE","ACTION_ROTATE","ACTION_TRANSFORM","ACTION_NONE","ACTION_RESIZE_NORTH","ACTION_RESIZE_EAST","ACTION_RESIZE_SOUTH","ACTION_RESIZE_WEST","ACTION_RESIZE_NORTHEAST","ACTION_RESIZE_NORTHWEST","ACTION_RESIZE_SOUTHEAST","ACTION_RESIZE_SOUTHWEST","ATTRIBUTE_ACTION","EVENT_TOUCH_END","EVENT_TOUCH_MOVE","EVENT_TOUCH_START","EVENT_POINTER_DOWN","EVENT_POINTER_MOVE","EVENT_POINTER_UP","EVENT_ERROR","EVENT_KEYDOWN","EVENT_LOAD","EVENT_WHEEL","EVENT_ACTION","EVENT_ACTION_END","EVENT_ACTION_MOVE","EVENT_ACTION_START","EVENT_CHANGE","EVENT_TRANSFORM","isString","isNaN","isNumber","isPositiveNumber","isUndefined","isObject","hasOwnProperty","isPlainObject","constructor","prototype","isFunction","isElement","REGEXP_CAMEL_CASE","toKebabCase","REGEXP_KEBAB_CASE","toCamelCase","substring","REGEXP_SPACES","off","target","listener","on","once","defaultEventOptions","emit","detail","resolvedPromise","nextTick","context","getOffset","element","documentElement","box","REGEXP_ANGLE_UNIT","toAngleInRadian","unit","SIZE_ADJUSTMENT_TYPE_CONTAIN","SIZE_ADJUSTMENT_TYPE_COVER","getAdjustedSizes","aspectRatio","width","height","isValidWidth","isValidHeight","adjustedWidth","multiplyMatrices","matrix","args","a1","b1","c1","d1","e1","f1","a2","b2","c2","d2","e2","f2","REGEXP_SUFFIX","DEFAULT_SHADOW_ROOT_MODE","shadowRoots","styleSheets","tagNames","supportsAdoptedStyleSheets","CropperElement","oldPropertyValue","newPropertyValue","styleSheet","styles","attribute","shadow","template","slot","properties","CropperCanvas","event","buttons","button","$pointers","action","identifier","pageX","pageY","pointerId","$action","pointer","pointers2","maxRotateRate","maxScaleRate","rotate","scale","centerX","centerY","pointer2","x1","y1","x2","y2","z1","z2","rotateRate","absRotateRate","scaleRate","absScaleRate","rotatable","scalable","reject","canvas","cropperImage","image","d","newE","newF","destWidth","destHeight","canvasCache","NATIVE_ATTRIBUTES","CropperImage","$image","$canvas","relatedEvent","$selection","x","y","cos","sin","scaleX","skewY","skewX","scaleY","clientRect","originX","originY","moveX","moveY","translateX","translateY","promise","onLoad","onError","size","parentElement","container","containerWidth","containerHeight","startX","startY","endX","endY","radian","radianX","radianY","oldMatrix","newMatrix","CropperHandle","CropperSelection","selections","selection","center","resize","initialCoverage","newSelection","activeSelection","relatedTarget","currentTarget","offset","activeElement","offsetX","offsetY","hasValidAspectRatio","newWidth","newHeight","newX","newY","_force","CropperCrosshair","CropperShade","ArrowsCenterIcon","TEXTAREA","SELECT","INPUT","CHECKBOX","ALERT","MessageDisplayMixin","_MessageDisplayMixinClass","message","MessageDisplayMixinClass","CropMode","MessageDisplayMixinElement","ZoomableImage","_old","imageWidth","imageHeight","normalizedRotation","displayedImageWidth","displayedImageHeight","rotatedCoords","cropperImageRect","cropperCanvasRect","transformValue","imageRect","canvasWidth","canvasHeight","widthScale","heightScale","boundingBox","inverseRotation","maxSelection","isSelectionHidden","hasNoSize","cropperCanvas","cropperSelection","cropperImageClone","zoom","crossorigin","styleMap","RobotoffQuestionForm","SignalWatcher","click","isLoading","BASE","ICON_BASE","RobotoffQuestion","Task","insightTypes","getMessageWrapper","questionsList","insightById","insightIdByProductCode","fetchNutrientInsights","insight","annotateNutrientsWithData","servingSize","clonedData","annotateNutrientWithoutData","taxonomies","nutrientTaxonomyById","nutrientTaxonomies","nutrientTaxonomyObj","getTaxonomyNameByLang","getTaxonomyNameByIdAndLang","taxonomy","getTaxonomyUnitById","fetchNutrientsTaxonomies","EDITABLE_UNITS","NUTRIENT_SERVING_SIZE_KEY","INSIGHTS_ANNOTATION_SIZE","NUTRIENT_SUFFIX","NUTRIENT_UNIT_SUFFIX","FORCED_UNITS_BY_NUTRIENTS_KEYS","getPossibleUnits","fallbackUnit","NUTRIENT_UNIT_NAME_PREFIX","BackgroundImageDirective","Directive","otherStyle","backgroundImage","directive","FOLKSONOMY_INPUT","AutocompleteInput","filtered","inputValue","suggestion","filteredSuggestions","suggestionsToShow","matching","classMap","SuggestionIcon","AddIcon","EyeVisibleIcon","EyeInvisibleIcon","ALLOWED_SPECIAL_VALUES","SERVING_SIZE_SELECT_NAME","RobotoffNutrientExtractionForm","column","nutrients","keysSet","entryA","entryB","nutrientKey","nutrimentsData","keySet","suffix","nutrientUnitKey","keyToAdd","countryKeys","robotoffSuggestion","selectInputUnit","answer","robotoffServingSize","onClick","suggestionValue","text","str","disabled","possibleUnits","inputName","currentUnit","selectsClasses","label","isHidden","insightAnnotationAnswer","valueCleaned","numberValue","nutrientAnotationForm","formValues","servingSizeInputValue","isUnit","isValid","validatedData","isAcceptLoading","nutrientId","alreadyAddedNutrients","filteredNutrientTaxonomies","nutrientTaxonomy","ProductFields","getFullImageUrl","imageUrl","KP_ATTRIBUTE_IMG","img","LanguageCodesMixin","CountryCodeMixin","ExternalLinkIcon","ProductLinkButton","DisplayProductLinkMixin","IMAGE_MAX_WIDTH","RobotoffNutrientExtraction","insights","imgUrl","ifDefined","ingredientSpellcheckInsights","fetchSpellcheckInsights","CheckIcon","CrossIcon","SkipIcon","EditIcon","InfoIcon","InfoButton","POPOVER","TEXT_CORRECTOR","ClickOutsideDirective","AsyncDirective","part","clickOutside","ChangeType","setPrototypeOf","isFrozen","getPrototypeOf","getOwnPropertyDescriptor","freeze","seal","create","apply","construct","func","thisArg","_len","_key","Func","_len2","_key2","arrayForEach","unapply","arrayLastIndexOf","arrayPop","arrayPush","arraySplice","stringToLowerCase","stringToString","stringMatch","stringReplace","stringIndexOf","stringTrim","objectHasOwnProperty","regExpTest","typeErrorCreate","unconstruct","_len3","_key3","_len4","_key4","addToSet","set","array","transformCaseFunc","lcElement","cleanArray","clone","object","newObject","lookupGetter","prop","desc","fallbackValue","html$1","svg$1","svgFilters","svgDisallowed","mathMl$1","mathMlDisallowed","svg","mathMl","xml","MUSTACHE_EXPR","ERB_EXPR","TMPLIT_EXPR","DATA_ATTR","ARIA_ATTR","IS_ALLOWED_URI","IS_SCRIPT_OR_DATA","ATTR_WHITESPACE","DOCTYPE_NAME","CUSTOM_ELEMENT","EXPRESSIONS","NODE_TYPE","getGlobal","_createTrustedTypesPolicy","trustedTypes","purifyHostElement","ATTR_NAME","policyName","scriptUrl","_createHooksMap","createDOMPurify","window","DOMPurify","root","document","originalDocument","currentScript","DocumentFragment","HTMLTemplateElement","Node","Element","NodeFilter","NamedNodeMap","HTMLFormElement","DOMParser","ElementPrototype","cloneNode","remove","getNextSibling","getChildNodes","getParentNode","trustedTypesPolicy","emptyHTML","implementation","createNodeIterator","createDocumentFragment","getElementsByTagName","importNode","hooks","IS_ALLOWED_URI$1","ALLOWED_TAGS","DEFAULT_ALLOWED_TAGS","ALLOWED_ATTR","DEFAULT_ALLOWED_ATTR","CUSTOM_ELEMENT_HANDLING","FORBID_TAGS","FORBID_ATTR","ALLOW_ARIA_ATTR","ALLOW_DATA_ATTR","ALLOW_UNKNOWN_PROTOCOLS","ALLOW_SELF_CLOSE_IN_ATTR","SAFE_FOR_TEMPLATES","SAFE_FOR_XML","WHOLE_DOCUMENT","SET_CONFIG","FORCE_BODY","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_TRUSTED_TYPE","SANITIZE_DOM","SANITIZE_NAMED_PROPS","SANITIZE_NAMED_PROPS_PREFIX","KEEP_CONTENT","IN_PLACE","USE_PROFILES","FORBID_CONTENTS","DEFAULT_FORBID_CONTENTS","DATA_URI_TAGS","DEFAULT_DATA_URI_TAGS","URI_SAFE_ATTRIBUTES","DEFAULT_URI_SAFE_ATTRIBUTES","MATHML_NAMESPACE","SVG_NAMESPACE","HTML_NAMESPACE","IS_EMPTY_INPUT","ALLOWED_NAMESPACES","DEFAULT_ALLOWED_NAMESPACES","MATHML_TEXT_INTEGRATION_POINTS","HTML_INTEGRATION_POINTS","COMMON_SVG_AND_HTML_ELEMENTS","PARSER_MEDIA_TYPE","SUPPORTED_PARSER_MEDIA_TYPES","DEFAULT_PARSER_MEDIA_TYPE","CONFIG","formElement","isRegexOrFunction","testValue","_parseConfig","cfg","ALL_SVG_TAGS","ALL_MATHML_TAGS","_checkValidNamespace","parent","tagName","parentTagName","_forceRemove","_removeAttribute","_initDocument","dirty","doc","leadingWhitespace","matches","dirtyPayload","_createNodeIterator","_isClobbered","_isNode","_executeHooks","currentNode","hook","_sanitizeElements","content","_isBasicCustomElement","parentNode","childNodes","childCount","childClone","expr","_isValidAttribute","lcTag","lcName","_sanitizeAttributes","attributes","hookEvent","attr","namespaceURI","attrValue","initValue","_sanitizeShadowDOM","fragment","shadowNode","shadowIterator","importedNode","returnNode","nodeIterator","serializedHTML","tag","entryPoint","hookFunction","purify","sanitizeHtml","unsafeHTML","Diff","oldStr","newStr","oldString","newString","oldTokens","newTokens","done","newLen","oldLen","editLength","maxEditLength","maxExecutionTime","abortAfterTimestamp","bestPath","newPos","minDiagonalToConsider","maxDiagonalToConsider","execEditLength","diagonalPath","basePath","removePath","addPath","canAdd","addPathNewPos","canRemove","exec","ret","added","removed","oldPosInc","last","oldPos","commonCount","left","right","chars","changeObjects","lastComponent","components","nextComponent","componentLen","componentPos","component","extendedWordChars","WordsWithSpaceDiff","regex","wordsWithSpaceDiff","diffWordsWithSpace","TextDiffMixin","TextCorrectorMixinClass","change","textToCompare","getValidHeadingLevel","headingLevel","defaultLevel","validLevels","level","getSubHeadingLevel","currentLevel","HeadingRenderer","classAttr","sanitizedHTML","TextCorrectorHighlight","_changedProperties","textarea","headingTag","TextCorrector","_","shortcut","loadingButton","changedProperties","changes","nextIndex","next","position","reset","className","cleanedValue","isCurrent","indexedGroupedChangeIndex","indexedGroupedChange","currentIndex","isValidate","keyboardShortcutText","filteredNotAnsweredChanges","notAnsweredChanges","nextFilteredNotAnsweredChanges","validate","items","groupedChange","groupedChangesIndex","confirmTitle","isSuccessLoading","successButton","RobotoffIngredientSpellcheck","title","original","CONTAINER","MODAL","ModalComponent","ingredientDetectionInsights","fetchIngredientsDetectionInsights","robotoffBoundingBoxToCropImageBoundingBox","xMin","yMin","xMax","yMax","cropImageBoundingBoxToRobotoffBoundingBox","RobotoffIngredientDetectionForm","ZoomableImage.CropMode","robotoffBoundingBox","bounding_box","RobotoffIngredientDetection","page","newIndex","RobotoffModal","robotoffContributionType","RobotoffContributionMessage","insightValues","fetchKnowledgePanels","pathParts","ActionElementRenderer","actionElement","actionText","actionDescription","TextElementRenderer","textContent","sanitizedContent","TableElementRenderer","tableData","columns","cell","TitledTextElementRenderer","extractImages","panels","nutritionImages","nutritionPanel","panelId","panel","htmlContent","imgRegex","extractNestedImages","referencedPanel","elements","PanelHeaderRenderer","PanelGroupImageRenderer","imageAlt","imageCaption","ImageRenderer","NutritionImageRenderer","PanelRenderer","subtitle","icon","PanelElementRenderer","subElement","PanelGroupElementRenderer","panelGroup","ElementRenderer","KnowledgePanelsComponent","errorMessage","panelsToRender","DarkModeListener","darkModeListener","DonationBanner","isDark","rootClasses","MobileBadges","language","campaign","href","src","alt","errorHandler","badge","filteredBadges","DownloadAppQrCode","BarcodeIcon","SearchIcon","CloseIcon","ConsoleLogMixin","time","now","BarcodeScanner","imageData","detector","barcodes","permissionStatus","track","video","processFrame","imageBitmap","DeleteModal","NewKeyModal","input","wikiUrl","FOLKSONOMY_BEARER_TOKEN_KEY","FOLKSONOMY_BEARER_DATE_KEY","getStoredToken","saveTokenToStorage","clearStoredToken","authByCookie","getValidToken","storedToken","makeAuthenticatedRequest","requestOptions","newToken","retryOptions","fetchProductProperties","addProductProperty","version","deleteProductProperty","updateProductProperty","fetchKeys","fetchProductsProperties","fetchValues","getUserInfo","fetchUserInfo","force","fetchedUserInfo","replaceValue","deleteValue","checkPropertyClash","renameProperty","deleteProperty","folksonomyApi","FolksonomyEditorRow","updatedProperty","deleteModal","newProperty","FolksonomyEditor","direction","valueA","valueB","product_properties","isActive","DualRangeSlider","numValue","newMinValue","newMaxValue","percent1","percent2","FolksonomyProperties","counts","p","countMin","countMax","valuesMin","valuesMax","currentUserInfo","matchesProperty","matchesCount","matchesValues","field","filterField","clashData","FolksonomyPropertyProducts","valueCountMap","valueItem","matchesBarcode","matchesValue","mode","isProductsView","currentData","totalData","ProductCard","score","matchStatus","isNavigatingToProduct","hasProductImage","matchTagInfo","cardClasses","L","O","G","E","xe","be","Re","C","Oe","j","se","ie","Te","F","we","Q","ye","Pe","U","Se","oe","$e","K","re","_e","Le","Me","ze","ae","Ae","D","W","le","Ee","ue","Ce","Ie","Be","pe","qe","ve","ce","De","He","Ze","Ge","Ne","je","Fe","q","Qe","he","de","Ue","X","Ke","N","We","I","M","Xe","ke","J","V","u","z","ge","fe","Je","g","T","H","ee","te","ne","me","Z","A","Y","P","$","R","S","B","SECONDS_A_MINUTE","SECONDS_A_HOUR","SECONDS_A_DAY","SECONDS_A_WEEK","MILLISECONDS_A_SECOND","MILLISECONDS_A_MINUTE","MILLISECONDS_A_HOUR","MILLISECONDS_A_DAY","MILLISECONDS_A_WEEK","MS","MIN","DATE","FORMAT_DEFAULT","INVALID_DATE_STRING","REGEX_PARSE","REGEX_FORMAT","en","padStart","string","length","pad","padZoneStr","instance","negMinutes","minutes","hourOffset","minuteOffset","monthDiff","wholeMonthDiff","anchor","C.M","anchor2","absFloor","prettyUnit","special","C.Y","C.W","C.D","C.DATE","C.H","C.MIN","C.S","C.MS","C.Q","Ls","IS_DAYJS","isDayjs","Dayjs","parseLocale","preset","isLocal","presetLower","presetSplit","dayjs","date","wrapper","Utils","parseDate","utc","C.REGEX_PARSE","ms","_proto","$d","C.INVALID_DATE_STRING","that","units","other","get","_startOf","_this","isStartOf","instanceFactory","ins","instanceFactorySet","slice","argumentStart","argumentEnd","$W","$M","$D","utcPad","weekStart","gap","arg","_int","_C$D$C$DATE$C$M$C$Y$C","_int2","number","_this2","_C$MIN$C$H$C$S$unit","step","C.MILLISECONDS_A_MINUTE","C.MILLISECONDS_A_HOUR","C.MILLISECONDS_A_SECOND","nextTimeStamp","formatStr","_this3","C.FORMAT_DEFAULT","zoneStr","$H","$m","weekdays","months","meridiem","getShort","arr","full","get$H","num","meridiemFunc","hour","minute","isLowercase","C.REGEX_FORMAT","$1","_float","_this4","zoneDelta","diff","getMonth","C.MILLISECONDS_A_WEEK","C.MILLISECONDS_A_DAY","nextLocaleName","proto","plugin","option","timestamp","NewsFeed","country","appVersion","currentLang","currentFullLang","rawData","filteredItems","marked","processedItems","newsDetailsMap","feedIds","feedItem","details","translation","fullLangKey","defaultTranslation","v1","parts1","parts2","p1Str","p2Str","p1Num","p2Num","processedNewsItems","currentCountry","currentAppVersion","startDate","endDate","hasUrl","placeholderId","placeholderContent","iconTemplate","contentTemplate","news"],"mappings":"4bAMaA,GAAe,KAMfC,GAAgB,CAC3B,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,MACA,KACA,MACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,IACF,EC5HA,IAAIC,GAAY,OAAO,eACnBC,GAAkB,CAACC,EAAKC,EAAKC,IAAUD,KAAOD,EAAMF,GAAUE,EAAKC,EAAK,CAAE,WAAY,GAAM,aAAc,GAAM,SAAU,GAAM,MAAAC,CAAK,CAAE,EAAIF,EAAIC,CAAG,EAAIC,EACtJC,GAAgB,CAACH,EAAKC,EAAKC,KAC7BH,GAAgBC,EAAK,OAAOC,GAAQ,SAAWA,EAAM,GAAKA,EAAKC,CAAK,EAC7DA,GAELE,GAAgB,CAACJ,EAAKK,EAAQC,IAAQ,CACxC,GAAI,CAACD,EAAO,IAAIL,CAAG,EACjB,MAAM,UAAU,UAAYM,CAAG,CACnC,EACIC,GAAc,CAACF,EAAQL,IAAQ,CACjC,GAAI,OAAOA,CAAG,IAAMA,EAClB,MAAM,UAAU,4CAA4C,EAC9D,OAAOK,EAAO,IAAIL,CAAG,CACvB,EACIQ,GAAe,CAACR,EAAKK,EAAQH,IAAU,CACzC,GAAIG,EAAO,IAAIL,CAAG,EAChB,MAAM,UAAU,mDAAmD,EACrEK,aAAkB,QAAUA,EAAO,IAAIL,CAAG,EAAIK,EAAO,IAAIL,EAAKE,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C,QAAAA,qBACK,OAASv2B,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AA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;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA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","x_google_ignoreList":[1,2,3,4,5,6,13,14,15,16,17,23,24,25,26,27,28,29,30,31,32,35,46,50,51,52,53,54,55,56,57,72,80,98,99,101,102,148,149,150,151,152]}