{"version":3,"file":"main.cjs","sources":["../src/component/layout/NotFound.vue","../src/provider/router.ts","../src/provider/html-meta-tag.ts","../src/provider/randomness.ts","../src/model/color.ts","../src/provider/color-palette.ts","../src/provider/color-scheme.ts","../src/component/global-controller/ColorSchemeSwitch.vue","../src/provider/status-box.ts","../src/component/StatusBox.vue","../src/component/global-controller/ColorPaletteTdContrast.vue","../src/component/global-controller/ColorPicker.vue","../src/component/global-controller/ButtonWithIcon.vue","../src/provider/html-element.ts","../src/component/global-controller/ButtonWithIconLink.vue","../src/provider/notification.ts","../src/component/layout/ButtonWithIconShowcase.vue","../src/component/layout/MainHeaderLogo.vue","../src/provider/menu.ts","../src/graphics/sbrul-shad-svg-v1.svg","../src/model/logo-section.ts","../src/provider/combinations.ts","../src/provider/z-index.ts","../src/component/layout/NotificationsArea.vue","../src/App.vue","../src/main.ts"],"sourcesContent":["<template>\n  <section>\n    <div>\n      <div>\n        <h1>Oh no! Anyway...</h1>\n        <p>\n          Looks like this page doesn't exist.\n          <router-link to=\"/\">\n            Click here to return to the homepage.\n          </router-link>\n        </p>\n      </div>\n    </div>\n  </section>\n</template>\n","import {\n  createRouter,\n  createWebHistory,\n  type Router,\n  type RouteRecordRaw,\n} from \"vue-router\";\nimport { type MenuItemAny } from \"./menu\";\nimport NotFound from \"../component/layout/NotFound.vue\";\n\nexport function getRouterForMenu(\n  menu: MenuItemAny[],\n  useDefault404: boolean = true,\n): Router {\n  const routes: RouteRecordRaw[] = [];\n  for (const menuItem of menu) {\n    routes.push({\n      path: menuItem.path,\n      name: menuItem.name,\n      component: menuItem.component, // Using a Promise<COMPONENT> should cause generating separate chunks and lazy loading them. Example: component: () => import('../views/ExampleView.vue')\n      props: menuItem.componentProps,\n      meta: {\n        title: menuItem.metaTitle,\n      },\n    });\n  }\n  if (useDefault404) {\n    routes.push(\n      {\n        path: \"/:pathMatch(.*)*\",\n        component: () => NotFound,\n        meta: {\n          title: \"404 not found\",\n        },\n      },\n      // {\n      //   path: \"/:pathMatch(.*)*\",\n      //   redirect: clientPaths._404,\n      // }\n    );\n  }\n  const router = createRouter({\n    history: createWebHistory(),\n    routes,\n    scrollBehavior: (to) =>\n      to.hash\n        ? { el: to.hash, behavior: \"smooth\" }\n        : { top: 0, left: 0, behavior: \"smooth\" },\n  });\n\n  router.beforeEach((to, _, next) => {\n    document.title = `${to.meta.title ?? \"\"}`;\n    next();\n  });\n\n  return router;\n}\n","/**\n * Adds a new meta tag with the given value.\n * @param name The name of the new meta tag.\n * @param content The value of the new meta tag.\n * @returns The new meta tag.\n */\nexport function addMetaTag(name: string, content: string): HTMLMetaElement {\n  const meta: HTMLMetaElement = document.createElement(\"meta\");\n  meta.name = name;\n  meta.content = content;\n  document.head.appendChild(meta);\n  return meta;\n}\n\n/**\n * Retrieves a meta tag by its name.\n * @param name Name of the meta tag to be retrieved.\n * @returns The retrieved meta tag or null if it doesn't exist.\n */\nexport function getMetaTag(name: string): HTMLMetaElement | null {\n  return document.head.querySelector(`meta[name=\"${name}\"]`);\n}\n\n/**\n * Retrieves a meta tag content by the name of the meta tag.\n * @param name Name of the meta tag to retrieve content from.\n * @returns The retrieved meta tag content or undefined.\n */\nexport function getMetaTagContent(name: string): string | undefined {\n  return getMetaTag(name)?.content;\n}\n\n/**\n * Makes sure that a meta tag exists.\n * If it exists, the value is ignored.\n * If it doesn't exist, it is created with the given value.\n * @param name Name of the meta tag to be ensured.\n * @param defaultContent The value to be used if the meta tag didn't exist.\n * @returns The edited meta tag.\n */\nexport function ensureMetaTagExistence(\n  name: string,\n  defaultContent: string,\n): HTMLMetaElement {\n  return getMetaTag(name) ?? addMetaTag(name, defaultContent);\n}\n\n/**\n * Creates a new meta tag if it doesn't exist or sets a value to an existing meta tag.\n * @param name Name of the meta tag to be set.\n * @param newContent Value to be set to the meta tag.\n * @returns The edited meta tag.\n */\nexport function ensureMetaTagContent(\n  name: string,\n  newContent: string,\n): HTMLMetaElement {\n  const meta = ensureMetaTagExistence(name, newContent);\n  return setMetaTagContent(meta, newContent);\n}\n\n/**\n * Sets a value to the given meta tag.\n * @param meta The meta tag to be edited.\n * @param content The new value to be set to the given meta tag.\n * @returns The meta tag.\n */\nexport function setMetaTagContent(\n  meta: HTMLMetaElement,\n  content: string,\n): HTMLMetaElement {\n  meta.setAttribute(\"content\", content);\n  return meta;\n}\n","/**\n * Get a pseudo-random integer: 0 <= result < maximum\n * @param maximum upper bound (excluded)\n */\nexport function getPseudoRandomInteger(maximum: number): number {\n  return Math.floor(Math.random() * maximum);\n}\n\n/**\n * Get pseudo-random integers: 0 <= results[i] < maximums[i]\n * @param maximums upper bounds (excluded)\n */\nexport function getPseudoRandomIntegers(maximums: number[]): number[] {\n  return maximums.map((n: number): number => getPseudoRandomInteger(n));\n}\n\n/**\n * Get pseudo-random bytes: 0 <= results < 256\n * @param count number of bytes to be generated\n */\nexport function getRandomBytes(count: number): number[] {\n  return getPseudoRandomIntegers(Array(count).fill(256));\n}\n\n/**\n * Get pseudo-random string of the specified characters.\n * @param charsCount number of characters to be returned\n * @param alphabet the characters to select uniformly from\n */\nexport function getPseudoRandomString(\n  charsCount: number = 32,\n  alphabet: string = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\",\n): string {\n  let result = \"\";\n  const alphabetLength = alphabet.length;\n  for (let i = 0; i < charsCount; i++) {\n    result += alphabet.charAt(Math.floor(Math.random() * alphabetLength));\n  }\n  return result;\n}\n\n/**\n * Get a pseudo-random item from the first array that is not in the second array.\n * @param array One of these items will be randomly selected.\n * @param notTheseItems None of these items will be selected.\n * @returns A random item form the first array and not from the second array.\n */\nexport function getPseudoRandomItem<T>(array: T[], notTheseItems: T[] = []): T {\n  const allowedItems = array.filter((x) => !notTheseItems.includes(x));\n  if (allowedItems.length === 0) throw new Error(\"No allowed item.\");\n  return allowedItems[getPseudoRandomInteger(allowedItems.length)];\n}\n","import { getPseudoRandomInteger } from \"../provider/randomness\";\n\nexport abstract class Color {\n  readonly alpha100: number;\n\n  get alpha255(): number {\n    return (this.alpha100 * 255) / 100;\n  }\n\n  get alpha1(): number {\n    return this.alpha100 / 100;\n  }\n\n  protected constructor(alpha: number | string = 100) {\n    this.alpha100 = Color.parseNumber(alpha, 100);\n  }\n\n  equals(\n    other: Color,\n    ignoreAlpha: boolean = false,\n    tolerance: number = 0,\n  ): boolean {\n    const thisRgba = this.rgba;\n    const otherRgba = other.rgba;\n    if (\n      !ignoreAlpha &&\n      Math.abs(thisRgba.alpha100 - otherRgba.alpha100) > tolerance\n    )\n      return false;\n    return (\n      Math.abs(thisRgba.red255 - otherRgba.red255) <= tolerance &&\n      Math.abs(thisRgba.green255 - otherRgba.green255) <= tolerance &&\n      Math.abs(thisRgba.blue255 - otherRgba.blue255) <= tolerance\n    );\n  }\n\n  abstract get rgba(): ColorRGBA;\n\n  abstract get hsla(): ColorHSLA;\n\n  getHexString(withAlpha: boolean = true): string {\n    const thisRgba = this.rgba;\n    const rgba255 = [thisRgba.red255, thisRgba.green255, thisRgba.blue255];\n    if (withAlpha) rgba255.push(thisRgba.alpha255);\n    const rgbaHex = rgba255.map((c: number): string =>\n      Math.round(c).toString(16).padStart(2, \"0\"),\n    );\n    return `#${rgbaHex.join(\"\")}`;\n  }\n\n  get hexStringWithAlpha(): string {\n    return this.getHexString(true);\n  }\n\n  get hexStringNoAlpha(): string {\n    return this.getHexString(false);\n  }\n\n  get rgbString(): string {\n    const thisRgba = this.rgba;\n    const rgb255 = [thisRgba.red255, thisRgba.green255, thisRgba.blue255];\n    return `rgb(${rgb255.join(\", \")})`;\n  }\n\n  toString(): string {\n    return this.hexStringWithAlpha;\n  }\n\n  static parse(input: string): Color {\n    input = input.toLowerCase();\n\n    if (/^#[0-9abcdef]{3,4}$/.test(input)) {\n      // parse: #RGB\n      // parse: #RGBA\n      let expanded = \"\";\n      for (const character of input) {\n        // duplicate all characters except for the first one which is \"#\"\n        expanded += expanded.length === 0 ? \"\" : `${character}`;\n        expanded += `${character}`;\n      }\n      return Color.parse(expanded);\n    }\n\n    if (/^#[0-9abcdef]{6}([0-9abcdef]{2})?$/.test(input)) {\n      // parse: #RRGGBB\n      // parse: #RRGGBBAA\n      const r = parseInt(input.substring(1, 3), 16);\n      const g = parseInt(input.substring(3, 5), 16);\n      const b = parseInt(input.substring(5, 7), 16);\n      const a =\n        input.length === 7\n          ? 100\n          : (parseInt(input.substring(7, 9), 16) * 100) / 255;\n      return new ColorRGBA(r, g, b, a);\n    }\n\n    input = input.replaceAll(\" \", \"\");\n\n    function getDigitsRegex(prefix: string, digitsCount: number): RegExp {\n      const digit = \"\\\\d+(\\\\.\\\\d+)?%?\";\n      // matches: D\n      // matches: D%\n      // matches: D.D\n      // matches: D.D%\n\n      const minus = [\"hsl\", \"hsla\"].some((p) => p === prefix) ? \"\\\\-?\" : \"\";\n\n      let result = \"\";\n      for (let i = 0; i < digitsCount; i++) {\n        if (result.length > 0) result += \",\";\n        result += digit;\n      }\n      return RegExp(`^${prefix}\\\\(${minus}${result}\\\\)$`);\n    }\n\n    if (getDigitsRegex(\"rgb\", 3).test(input)) {\n      // parse: rgb(R,G,B)\n      const [r, g, b] = input\n        .replace(/^rgb\\(/, \"\")\n        .replace(/\\)$/, \"\")\n        .split(\",\");\n      return new ColorRGBA(r, g, b);\n    }\n\n    if (getDigitsRegex(\"rgba\", 4).test(input)) {\n      // parse: rgba(R,G,B,A)\n      const [r, g, b, a] = input\n        .replace(/^rgba\\(/, \"\")\n        .replace(/\\)$/, \"\")\n        .split(\",\");\n      return new ColorRGBA(r, g, b, a);\n    }\n\n    if (getDigitsRegex(\"hsl\", 3).test(input)) {\n      // parse: hsl(H,S,L)\n      const [h, s, l] = input\n        .replace(/^hsl\\(/, \"\")\n        .replace(/\\)$/, \"\")\n        .split(\",\");\n      return new ColorHSLA(h, s, l);\n    }\n\n    if (getDigitsRegex(\"hsla\", 4).test(input)) {\n      // parse: hsla(H,S,L,A)\n      const [h, s, l, a] = input\n        .replace(/^hsla\\(/, \"\")\n        .replace(/\\)$/, \"\")\n        .split(\",\");\n      return new ColorHSLA(h, s, l, a);\n    }\n\n    throw new Error(`Unexpected format of color: ${input}`);\n  }\n\n  static parseNumber(\n    value: number | string,\n    maximumValue: number,\n    allowModulo: boolean = false,\n  ): number {\n    value = value.toString();\n    const isPercentage = value.endsWith(\"%\");\n    value = Number(value.replace(/%$/, \"\"));\n    if (isPercentage) value = (value * maximumValue) / 100;\n\n    if (allowModulo) {\n      value = value % maximumValue;\n      if (value < 0) value += maximumValue;\n    }\n\n    if (value < 0) throw new Error(`Color component value ${value} < 0.`);\n    if (value > maximumValue)\n      throw new Error(`Color component value ${value} > ${maximumValue}.`);\n\n    return value;\n  }\n\n  get relativeLuminance(): number {\n    const thisRgba = this.rgba;\n    const color_1 = [thisRgba.red1, thisRgba.green1, thisRgba.blue1];\n    const partialLuminance = color_1.map(\n      (c) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4), // to power 2.4\n    );\n    const [R, G, B] = partialLuminance;\n    return 0.2126 * R + 0.7152 * G + 0.0722 * B;\n  }\n\n  /**\n   * Compute the contrast ratio of 2 colors.\n   * @param other The other color.\n   * @returns The value of contrast ratio.\n   */\n  colorsContrastRatio(other: Color): number {\n    const luminances = [this.rgba, other.rgba]\n      .map((c) => c.relativeLuminance)\n      .sort((a, b) => a - b); // the default .sort() would be alphabetical: [1, 10, 2, 30, 5]\n    // Contrast ratio = (Y_lighter + 0.05) / (Y_darker + 0.05)\n    return (luminances[1] + 0.05) / (luminances[0] + 0.05);\n  }\n\n  static get randomColor(): Color {\n    return new ColorRGBA(\n      getPseudoRandomInteger(256),\n      getPseudoRandomInteger(256),\n      getPseudoRandomInteger(256),\n    );\n  }\n}\n\nexport class ColorRGBA extends Color {\n  readonly red255: number;\n  readonly green255: number;\n  readonly blue255: number;\n\n  get red1(): number {\n    return this.red255 / 255;\n  }\n\n  get green1(): number {\n    return this.green255 / 255;\n  }\n\n  get blue1(): number {\n    return this.blue255 / 255;\n  }\n\n  constructor(\n    red: number | string,\n    green: number | string,\n    blue: number | string,\n    alpha: number | string = 100,\n  ) {\n    super(alpha);\n\n    this.red255 = Color.parseNumber(red, 255);\n    this.green255 = Color.parseNumber(green, 255);\n    this.blue255 = Color.parseNumber(blue, 255);\n  }\n\n  get rgba(): ColorRGBA {\n    return this;\n  }\n\n  get hsla(): ColorHSLA {\n    const red1 = this.red1;\n    const green1 = this.green1;\n    const blue1 = this.blue1;\n\n    const max1 = Math.max(red1, green1, blue1);\n    const min1 = Math.min(red1, green1, blue1);\n    const max1MinusMin1 = max1 - min1;\n    const max1PlusMin1 = max1 + min1;\n\n    let hue6;\n    switch (max1) {\n      case min1:\n        hue6 = 0;\n        break;\n      case red1:\n        hue6 = (green1 - blue1) / max1MinusMin1;\n        break;\n      case green1:\n        hue6 = 2 + (blue1 - red1) / max1MinusMin1;\n        break;\n      case blue1:\n      default:\n        hue6 = 4 + (red1 - green1) / max1MinusMin1;\n        break;\n    }\n    let hue360 = hue6 * 60;\n    if (hue360 < 0) hue360 += 360;\n\n    let saturation1;\n    if (max1 === min1) saturation1 = 0;\n    else if (max1PlusMin1 <= 1) saturation1 = max1MinusMin1 / max1PlusMin1;\n    else saturation1 = max1MinusMin1 / (2 - max1PlusMin1);\n    const saturation100 = saturation1 * 100;\n\n    const lightness1 = max1PlusMin1 / 2;\n    const lightness100 = lightness1 * 100;\n\n    return new ColorHSLA(hue360, saturation100, lightness100, this.alpha100);\n  }\n}\n\nexport class ColorHSLA extends Color {\n  readonly hue360: number;\n  readonly saturation100: number;\n  readonly lightness100: number;\n\n  get saturation1(): number {\n    return this.saturation100 / 100;\n  }\n\n  get lightness1(): number {\n    return this.lightness100 / 100;\n  }\n\n  constructor(\n    hue: number | string,\n    saturation: number | string,\n    lightness: number | string,\n    alpha: number | string = 100,\n  ) {\n    super(alpha);\n\n    this.hue360 = Color.parseNumber(hue, 360, true);\n    this.saturation100 = Color.parseNumber(saturation, 100);\n    this.lightness100 = Color.parseNumber(lightness, 100);\n  }\n\n  get hsla(): ColorHSLA {\n    return this;\n  }\n\n  get rgba(): ColorRGBA {\n    const saturation1 = this.saturation1;\n    const lightness1 = this.lightness1;\n    const hue360 = this.hue360;\n\n    const f = (n: number): number => {\n      const a = saturation1 * Math.min(lightness1, 1 - lightness1);\n      const k = (n + hue360 / 30) % 12;\n      return lightness1 - a * Math.max(-1, Math.min(k - 3, Math.min(9 - k, 1)));\n    };\n\n    return new ColorRGBA(255 * f(0), 255 * f(8), 255 * f(4), this.alpha100);\n  }\n}\n","import { ensureMetaTagContent } from \"./html-meta-tag\";\nimport { Color } from \"../model/color\";\n\ntype ColorAndComplement = {\n  value: Color;\n  complementValue: Color;\n};\n\nexport type ColorPalette = {\n  [color: string]: ColorAndComplement;\n};\n\n/**\n * The default values of colors.\n */\nexport const defaultColors: ColorPalette = Object.freeze({\n  primary: {\n    value: Color.parse(\"#7c2e9c\"),\n    complementValue: Color.parse(\"#ffffff\"),\n  },\n  secondary: {\n    value: Color.parse(\"#edbefe\"),\n    complementValue: Color.parse(\"#000000\"),\n  },\n  success: {\n    value: Color.parse(\"#b3ff80\"),\n    complementValue: Color.parse(\"#000000\"),\n  },\n  info: {\n    value: Color.parse(\"#90aafe\"),\n    complementValue: Color.parse(\"#000000\"),\n  },\n  warn: {\n    value: Color.parse(\"#fec17c\"),\n    complementValue: Color.parse(\"#000000\"),\n  },\n  error: {\n    value: Color.parse(\"#ff7a85\"),\n    complementValue: Color.parse(\"#000000\"),\n  },\n});\n\ntype PlainColorName = keyof typeof defaultColors;\n/**\n * Color valid variable names.\n */\nexport type ValidColorName =\n  | `color-${PlainColorName}`\n  | `color-${PlainColorName}-complement`;\n\nlet root: HTMLElement | null = null;\n\nfunction ensureRootObjects(): HTMLElement {\n  if (root === null) {\n    root = document.querySelector(\":root\") as HTMLElement;\n  }\n  return root;\n}\n\nfunction getRootStyleProperty(propertyName: string): string {\n  return getComputedStyle(ensureRootObjects()).getPropertyValue(propertyName);\n}\n\nfunction setRootStyleProperty(propertyName: string, propertyValue: string) {\n  return ensureRootObjects().style.setProperty(propertyName, propertyValue);\n}\n\n/**\n * Sets the CSS color variable.\n * @param colorName CSS variable name associated with the color.\n * @param colorValue CSS color value to be set.\n */\nexport function setColor(\n  colorName: ValidColorName | \"default-bg-color\",\n  colorValue: Color,\n) {\n  const hexString = colorValue.hexStringWithAlpha;\n  setRootStyleProperty(`--${colorName}`, hexString);\n  if (colorName === \"color-primary\")\n    ensureMetaTagContent(\"theme-color\", hexString);\n}\n\n/**\n * Retrieves the currently set CSS color variable value based the color name.\n * @param colorName Name of the color to be retrieved.\n * @returns Color value.\n */\nexport function getCurrentColor(\n  colorName: ValidColorName | \"default-bg-color\",\n): Color {\n  const defaultColor = Color.parse(\"#808080\");\n  const retrievedValue = getRootStyleProperty(`--${colorName}`); // empty string if not set\n\n  return retrievedValue.trim() === \"\"\n    ? defaultColor\n    : Color.parse(retrievedValue);\n}\n\n/**\n * Compose color variable name.\n * @param plainColorName The basic name of the color.\n * @returns Variable name in the \"color-${name}\" format.\n */\nexport function getColorNameFromPlainColorName(\n  plainColorName: keyof typeof defaultColors,\n): ValidColorName {\n  return `color-${plainColorName}`;\n}\n\n/**\n * Compose color complement variable name.\n * @param plainColorName The basic name of the color.\n * @returns Variable name in the \"color-${name}-complement\" format.\n */\nexport function getColorNameComplementFromPlainColorName(\n  plainColorName: keyof typeof defaultColors,\n): ValidColorName {\n  return `color-${plainColorName}-complement`;\n}\n\n/**\n * Set the default CSS color variables.\n */\nexport function setColors(colorPalette: ColorPalette) {\n  for (const [key, value] of Object.entries(colorPalette)) {\n    setColor(`color-${key}`, value.value);\n    setColor(`color-${key}-complement`, value.complementValue);\n  }\n}\n\n/**\n * Set the default CSS color variables.\n */\nexport function setDefaultColors() {\n  setColors(defaultColors);\n}\n\n/**\n * Select a value depending on contrast ratio.\n * @param contrastRatio It is decided based on this contrast ration. Valid values are 1-21\n * @param ok This value is returned for contrast ratio 7-21\n * @param meh This value is returned for contrast ratio 4.5-7\n * @param bad This value is returned for contrast ratio 7-21\n * @returns One of the provided values depending on the contrast ratio.\n */\nexport function selectByContrastRatio<T>(\n  contrastRatio: number,\n  ok: T,\n  meh: T,\n  bad: T,\n): T {\n  if (contrastRatio < 1 || 21 < contrastRatio)\n    throw new Error(`Invalid contrast ration value: ${contrastRatio}`);\n  if (contrastRatio > 7) {\n    return ok;\n  }\n  if (contrastRatio < 4.5) {\n    return bad;\n  }\n  return meh;\n}\n","import { ensureMetaTagContent, getMetaTagContent } from \"./html-meta-tag\";\nimport { Color, ColorRGBA } from \"../model/color\";\nimport { setColor } from \"./color-palette\";\n\nconst colorSchemesDefinition = {\n  dark: { backgroundColor: new ColorRGBA(0, 0, 0) },\n  light: { backgroundColor: new ColorRGBA(255, 255, 255) },\n};\n/**\n * Supported values of color scheme names.\n */\nexport type Scheme = keyof typeof colorSchemesDefinition;\n/**\n * List of supported color schemes.\n */\nexport const supportedColorSchemes = Object.freeze(\n  Object.keys(colorSchemesDefinition),\n) as Scheme[];\n\n/**\n * Sets a color scheme to the \"color-scheme\" meta tag.\n * @param scheme The value to be set.\n */\nexport function setColorScheme(scheme: Scheme) {\n  ensureMetaTagContent(\"color-scheme\", scheme);\n}\n\n/**\n * Gets the currently set color scheme in the \"color-scheme\" meta tag.\n * @returns The currently set color scheme.\n */\nexport function getColorSchemeConfigured(): Scheme | undefined {\n  const configuredScheme = getMetaTagContent(\"color-scheme\");\n\n  // nothing found\n  if (!configuredScheme) return undefined;\n\n  // found one of the supported - exactly\n  if (supportedColorSchemes.some((o) => o === configuredScheme))\n    return configuredScheme as Scheme;\n\n  // found one of the supported - substring whole word\n  for (const supportedScheme of supportedColorSchemes) {\n    if (RegExp(`\\\\b${supportedScheme}\\\\b`).exec(configuredScheme))\n      return supportedScheme;\n  }\n\n  // found one of the supported - substring\n  for (const supportedScheme of supportedColorSchemes) {\n    if (configuredScheme.includes(supportedScheme)) return supportedScheme;\n  }\n\n  // nothing useful found\n  return undefined;\n}\n\n/**\n * Obtains the preferred color scheme from the browser.\n * If none of the supported schemes is preferred, returns the first supported scheme.\n * @returns The preferred scheme if it is supported. The first supported scheme otherwise.\n */\nexport function getColorSchemePreferredOrDefault(): Scheme {\n  for (const colorScheme of supportedColorSchemes) {\n    if (window.matchMedia(`(prefers-color-scheme: ${colorScheme})`).matches)\n      return colorScheme;\n  }\n  return supportedColorSchemes[0];\n}\n\n/**\n * Gets the currently set color scheme in the \"color-scheme\" meta tag.\n * If it is not set, gets the preferred color scheme from the browser.\n * If none of the preferred schemes is supported, gets the first supported scheme.\n * @returns The currently set or the preferred color scheme.\n */\nexport function getColorSchemeConfiguredOrPreferred(): Scheme {\n  return getColorSchemeConfigured() ?? getColorSchemePreferredOrDefault();\n}\n\nexport function getDefaultBackgroundColor(bgColorIfNotFound?: Color): Color {\n  for (const element of [\n    document.documentElement, // background of the document\n    document.body, // background of the body\n  ]) {\n    const result = Color.parse(getComputedStyle(element).backgroundColor);\n    if (result.alpha100 > 50) return result;\n  }\n\n  // color not found\n  return (\n    bgColorIfNotFound ?? // pre-selected\n    new ColorRGBA(128, 128, 128) // grey\n  );\n}\n\nexport function setDefaultBackgroundColor(bgColorIfNotFound?: Color): Color {\n  const bgColor = getDefaultBackgroundColor(bgColorIfNotFound);\n  setColor(\"default-bg-color\", bgColor);\n  return bgColor;\n}\n\nexport function getColorSchemeDefaultBackgroundColor(scheme: Scheme): Color {\n  return colorSchemesDefinition[scheme].backgroundColor;\n}\n","<script setup lang=\"ts\">\nimport { defineStore } from \"pinia\";\nimport { faCircleHalfStroke } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n  supportedColorSchemes,\n  getColorSchemeConfiguredOrPreferred,\n  type Scheme,\n  setColorScheme,\n  setDefaultBackgroundColor,\n  getColorSchemeDefaultBackgroundColor,\n} from \"../../provider/color-scheme\";\nimport { FontAwesomeIcon } from \"@fortawesome/vue-fontawesome\";\n\nconst useDemessifierGuiColorScheme = defineStore({\n  id: \"demessifier-gui:color-scheme\",\n  state: () => {\n    return {\n      colorScheme: getColorSchemeConfiguredOrPreferred(), // share this as a global variable between all ColorSchemeSwitch instances\n    };\n  },\n  actions: {\n    switchSchemeTo(scheme: Scheme) {\n      this.colorScheme = scheme;\n      setColorScheme(scheme);\n      setDefaultBackgroundColor(getColorSchemeDefaultBackgroundColor(scheme));\n    },\n    reapplyScheme() {\n      this.switchSchemeTo(this.colorScheme);\n    },\n  },\n});\n\nconst colorSchemeStore = useDemessifierGuiColorScheme();\ncolorSchemeStore.reapplyScheme();\n</script>\n\n<template>\n  <label>\n    <FontAwesomeIcon :icon=\"faCircleHalfStroke\" />\n    &nbsp; Color scheme:\n    <select\n      v-model=\"colorSchemeStore.colorScheme\"\n      @change=\"colorSchemeStore.reapplyScheme()\"\n    >\n      <option\n        v-for=\"scheme in supportedColorSchemes\"\n        :key=\"scheme\"\n        :value=\"scheme\"\n      >\n        {{ scheme }}\n      </option>\n    </select>\n  </label>\n</template>\n\n<style lang=\"scss\" scoped>\n.buttons {\n  display: flex;\n  flex-direction: column;\n}\n</style>\n","import {\n  getColorNameComplementFromPlainColorName,\n  getColorNameFromPlainColorName,\n  ValidColorName,\n} from \"./color-palette\";\nimport { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport {\n  faCircleCheck,\n  faCircleExclamation,\n  faCircleInfo,\n  faTriangleExclamation,\n} from \"@fortawesome/free-solid-svg-icons\";\n\n/**\n * FontAwesome icons for the individual box flavors.\n */\nconst statusBoxIcons = Object.freeze({\n  success: faCircleCheck,\n  info: faCircleInfo,\n  warn: faCircleExclamation,\n  error: faTriangleExclamation,\n});\n\n/**\n * Box flavor.\n */\nexport type StatusBoxFlavorName = keyof typeof statusBoxIcons;\n\n/**\n * Get the list of all box flavors.\n * @returns The list of all box flavors.\n */\nexport function getAllStatusBoxFlavors(): StatusBoxFlavorName[] {\n  return Object.keys(statusBoxIcons) as StatusBoxFlavorName[];\n}\n\n/**\n * Flavor properties for boxes.\n */\nexport type StatusBoxFlavorItem = {\n  name: StatusBoxFlavorName;\n  icon: IconDefinition;\n  color: ValidColorName;\n  bgColor: ValidColorName;\n};\n\n/**\n * Get flavor properties for the given box flavor.\n * @param name Box flavor.\n * @returns Flavor properties for the given box flavor.\n */\nexport function getFlavorItem(name: StatusBoxFlavorName): StatusBoxFlavorItem {\n  return {\n    name: name,\n    icon: statusBoxIcons[name],\n    color: getColorNameComplementFromPlainColorName(name),\n    bgColor: getColorNameFromPlainColorName(name),\n  };\n}\n\nconst statusBoxFlavorPreparation: { [key: string]: StatusBoxFlavorItem } = {};\nfor (const boxFlavor of getAllStatusBoxFlavors()) {\n  statusBoxFlavorPreparation[boxFlavor] = getFlavorItem(boxFlavor);\n}\n/**\n * FontAwesome icons for the individual box flavors.\n */\nexport const statusBoxFlavor = Object.freeze(statusBoxFlavorPreparation);\n","<script setup lang=\"ts\">\nimport { computed, type ComputedRef, ref, useSlots } from \"vue\";\nimport { FontAwesomeIcon } from \"@fortawesome/vue-fontawesome\";\nimport {\n  statusBoxFlavor,\n  type StatusBoxFlavorItem,\n  type StatusBoxFlavorName,\n} from \"../provider/status-box\";\nimport { faCircleXmark, faThumbTack } from \"@fortawesome/free-solid-svg-icons\";\n\ninterface Props {\n  /**\n   * Headline of the box.\n   * This is shown in the tooltip when the box is minimized.\n   */\n  headlineText: string;\n  /**\n   * Determines color and icon of the box.\n   */\n  boxFlavorName: StatusBoxFlavorName;\n  initializeMinimized?: boolean;\n  /**\n   * Whether the box can be pinned.\n   * Pinning emits and event that has to be handled by the parent component.\n   */\n  canBePinned?: boolean;\n  /**\n   * Whether it can be closed.\n   * Closing emits an event that has to be handled by the parent component.\n   */\n  canBeClosed?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n  initializeMinimized: false,\n  canBePinned: false,\n  canBeClosed: false,\n});\n\nconst emit = defineEmits([\"close-status-box\", \"pin-status-box\"]);\n\nconst boxType: ComputedRef<StatusBoxFlavorItem> = computed(\n  () => statusBoxFlavor[props.boxFlavorName],\n);\nconst unMinimizeTooltip = `Expand: \\n${props.headlineText}`;\nconst minimized = ref(props.initializeMinimized);\nconst boxColor = computed(() => `var(--${boxType.value.color})`);\nconst boxBgColor = computed(() => `var(--${boxType.value.bgColor})`);\n\nfunction switchMinimized() {\n  minimized.value = !minimized.value;\n}\n\nfunction unMinimize() {\n  minimized.value = false;\n}\n</script>\n\n<template>\n  <div\n    class=\"status-box\"\n    :class=\"{ minimized: minimized, full: !minimized }\"\n    :title=\"minimized ? unMinimizeTooltip : ''\"\n    @click=\"unMinimize\"\n  >\n    <div class=\"buttons\" v-if=\"!minimized && (canBeClosed || canBePinned)\">\n      <span class=\"icon-button pin\"\n        ><FontAwesomeIcon\n          v-if=\"canBePinned\"\n          :icon=\"faThumbTack\"\n          @click=\"emit('pin-status-box')\"\n          title=\"Pin\"\n        ></FontAwesomeIcon\n      ></span>\n      <span class=\"spring\"></span>\n      <span class=\"icon-button close\"\n        ><FontAwesomeIcon\n          v-if=\"canBeClosed\"\n          :icon=\"faCircleXmark\"\n          @click=\"emit('close-status-box')\"\n          title=\"Close\"\n        ></FontAwesomeIcon\n      ></span>\n    </div>\n    <div\n      class=\"header\"\n      @click.stop=\"switchMinimized\"\n      :title=\"minimized ? unMinimizeTooltip : 'Minimize'\"\n    >\n      <h3>\n        <FontAwesomeIcon :icon=\"boxType.icon\" />\n        <span v-if=\"!minimized\">{{ headlineText }}</span>\n      </h3>\n    </div>\n    <div class=\"content\" v-if=\"!minimized && !!useSlots()['default']\">\n      <!-- @slot Contents of the box. -->\n      <slot></slot>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.status-box {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n\n  gap: 1em;\n  padding: 1em;\n  border: 2px solid v-bind(boxBgColor);\n  height: fit-content;\n  width: fit-content;\n  transition:\n    width 300ms ease,\n    height 300ms ease; /* doesn't work with fit-content */\n\n  &.minimized {\n    width: fit-content;\n    cursor: pointer;\n    background-color: v-bind(boxBgColor);\n\n    div.header {\n      h3 {\n        margin: 0;\n      }\n    }\n  }\n\n  &.full {\n    width: auto;\n\n    div.header {\n      cursor: pointer;\n      border-radius: 0.25rem;\n\n      h3 {\n        padding: 0 1em;\n      }\n    }\n  }\n\n  div.buttons {\n    display: flex;\n    flex-direction: row;\n    flex-wrap: nowrap;\n\n    color: v-bind(boxBgColor);\n\n    span {\n      padding: -1em 0 0 0;\n\n      &.spring {\n        width: 100%;\n      }\n\n      &.icon-button {\n        cursor: pointer;\n\n        &:hover {\n          color: initial;\n        }\n      }\n    }\n  }\n\n  div.header {\n    color: v-bind(boxColor);\n    background-color: v-bind(boxBgColor);\n    margin: 0;\n\n    h3 {\n      transition: all 300ms ease;\n      width: fit-content;\n\n      span {\n        padding: 0 1em;\n      }\n    }\n  }\n\n  div.content {\n    overflow: auto;\n\n    hr {\n      border-color: v-bind(boxBgColor);\n    }\n  }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { selectByContrastRatio } from \"../../provider/color-palette\";\nimport { FontAwesomeIcon } from \"@fortawesome/vue-fontawesome\";\nimport { computed, ComputedRef } from \"vue\";\nimport { getFlavorItem, StatusBoxFlavorItem } from \"../../provider/status-box\";\nimport { Color } from \"../../model/color\";\n\ninterface Props {\n  colorValue: Color;\n  otherColorValue: Color;\n}\n\nconst props = defineProps<Props>();\n\nconst contrast: ComputedRef<number> = computed(() =>\n  props.colorValue.colorsContrastRatio(props.otherColorValue),\n);\nconst flavor: ComputedRef<StatusBoxFlavorItem> = computed(() =>\n  getFlavorItem(\n    selectByContrastRatio(contrast.value, \"success\", \"warn\", \"error\"),\n  ),\n);\n</script>\n\n<template>\n  <td class=\"contrast\" :class=\"`${flavor.name}`\">\n    <span>\n      <FontAwesomeIcon :icon=\"flavor.icon\" />\n      {{ contrast.toFixed(2) }}\n    </span>\n  </td>\n</template>\n\n<style lang=\"scss\" scoped>\n$colorNames: success, warn, error;\n@each $colorName in $colorNames {\n  td.#{$colorName} {\n    background-color: var(--color-#{$colorName});\n\n    span {\n      color: var(--color-#{$colorName}-complement);\n    }\n  }\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n  defaultColors,\n  getColorNameComplementFromPlainColorName,\n  getColorNameFromPlainColorName,\n  getCurrentColor,\n  setColor,\n  type ValidColorName,\n} from \"../../provider/color-palette\";\nimport StatusBox from \"../StatusBox.vue\";\nimport ColorPaletteTdContrast from \"./ColorPaletteTdContrast.vue\";\nimport { type Ref, ref } from \"vue\";\nimport { Color } from \"../../model/color\";\n\nconst COLOR_NAME = \"color_name\";\n\ntype ColorValue = {\n  [key: string]: Ref<Color>;\n};\nconst colorValues: ColorValue = {};\nfor (const colorName of Object.keys(defaultColors)) {\n  colorValues[getColorNameFromPlainColorName(colorName)] = ref(\n    getCurrentColor(getColorNameFromPlainColorName(colorName)),\n  );\n  colorValues[getColorNameComplementFromPlainColorName(colorName)] = ref(\n    getCurrentColor(getColorNameComplementFromPlainColorName(colorName)),\n  );\n}\n\nfunction applyColor(event: Event) {\n  const input = event.target as HTMLInputElement;\n  const colorValue = Color.parse(input.value);\n  const colorName = input.dataset[COLOR_NAME] as ValidColorName;\n  if (!colorName)\n    throw new Error(`Data field '${COLOR_NAME}' not found in input element.`);\n  setColor(colorName, colorValue);\n  colorValues[colorName].value = colorValue;\n}\n\nfunction createDataAttribute(name: string, value: ValidColorName) {\n  return { [`data-${name}`]: value };\n}\n</script>\n\n<template>\n  <div class=\"content width-full\">\n    <div\n      v-for=\"colorName in Object.keys(defaultColors)\"\n      :key=\"colorName\"\n      class=\"row\"\n    >\n      <div\n        class=\"test-field left\"\n        :class=\"getColorNameFromPlainColorName(colorName)\"\n      >\n        <label>\n          {{ colorName }} color\n          <input\n            type=\"color\"\n            v-bind=\"\n              createDataAttribute(\n                COLOR_NAME,\n                getColorNameFromPlainColorName(colorName),\n              )\n            \"\n            :value=\"\n              getCurrentColor(getColorNameFromPlainColorName(colorName))\n                .hexStringNoAlpha\n            \"\n            @change=\"applyColor\"\n          />\n        </label>\n      </div>\n      <div\n        class=\"test-field right\"\n        :class=\"getColorNameComplementFromPlainColorName(colorName)\"\n      >\n        <label>\n          <input\n            type=\"color\"\n            v-bind=\"\n              createDataAttribute(\n                COLOR_NAME,\n                getColorNameComplementFromPlainColorName(colorName),\n              )\n            \"\n            :value=\"\n              getCurrentColor(\n                getColorNameComplementFromPlainColorName(colorName),\n              ).hexStringNoAlpha\n            \"\n            @change=\"applyColor\"\n          />\n          color complement for {{ colorName }}\n        </label>\n      </div>\n    </div>\n    <div class=\"row\">\n      <table>\n        <thead>\n          <tr>\n            <th scope=\"col\">Example</th>\n            <th scope=\"col\">Name</th>\n            <th scope=\"col\">Contrast ratio</th>\n            <th scope=\"col\">Example black</th>\n            <th scope=\"col\">Contrast black</th>\n            <th scope=\"col\">Example white</th>\n            <th scope=\"col\">Contrast white</th>\n          </tr>\n        </thead>\n        <tbody>\n          <tr\n            v-for=\"colorName in Object.keys(defaultColors)\"\n            :key=\"colorName\"\n            :class=\"colorName\"\n          >\n            <td :class=\"colorName\">\n              <span> Example </span>\n            </td>\n            <td>{{ colorName }}</td>\n            <ColorPaletteTdContrast\n              :color-value=\"\n                colorValues[getColorNameFromPlainColorName(colorName)].value\n              \"\n              :other-color-value=\"\n                colorValues[getColorNameComplementFromPlainColorName(colorName)]\n                  .value\n              \"\n            ></ColorPaletteTdContrast>\n            <td>\n              <span :class=\"`${colorName}-black`\">X</span>\n              &nbsp;\n              <span :class=\"`black-${colorName}`\">X</span>\n            </td>\n            <ColorPaletteTdContrast\n              :color-value=\"\n                colorValues[getColorNameFromPlainColorName(colorName)].value\n              \"\n              :other-color-value=\"Color.parse('#000')\"\n            ></ColorPaletteTdContrast>\n            <td>\n              <span :class=\"`${colorName}-white`\">X</span>\n              &nbsp;\n              <span :class=\"`white-${colorName}`\">X</span>\n            </td>\n            <ColorPaletteTdContrast\n              :color-value=\"\n                colorValues[getColorNameFromPlainColorName(colorName)].value\n              \"\n              :other-color-value=\"Color.parse('#FFF')\"\n            ></ColorPaletteTdContrast>\n          </tr>\n        </tbody>\n        <tfoot>\n          <tr>\n            <th scope=\"col\">Example</th>\n            <th scope=\"col\">Name</th>\n            <th scope=\"col\">Contrast ratio</th>\n            <th scope=\"col\">Example black</th>\n            <th scope=\"col\">Contrast black</th>\n            <th scope=\"col\">Example white</th>\n            <th scope=\"col\">Contrast white</th>\n          </tr>\n        </tfoot>\n      </table>\n    </div>\n    <StatusBox box-flavor-name=\"info\" headline-text=\"Contrast ratio\">\n      <table>\n        <thead>\n          <tr>\n            <th>From</th>\n            <th>To</th>\n            <th>Status</th>\n          </tr>\n        </thead>\n        <tbody>\n          <tr>\n            <td>1</td>\n            <td>4.5</td>\n            <td>bad</td>\n          </tr>\n          <tr>\n            <td>4.5</td>\n            <td>7</td>\n            <td>meh</td>\n          </tr>\n          <tr>\n            <td>7</td>\n            <td>21</td>\n            <td>good</td>\n          </tr>\n        </tbody>\n      </table>\n    </StatusBox>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.content {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  align-items: stretch;\n  gap: 1em;\n  padding: 1em 0;\n}\n\n.row {\n  display: flex;\n  flex-direction: row;\n  flex-wrap: nowrap;\n  align-items: stretch;\n}\n\n.test-field {\n  padding: 0.5em 1em;\n\n  &.left {\n    text-align: right;\n    width: 40%;\n  }\n\n  &.right {\n    text-align: left;\n    width: 60%;\n  }\n}\n\ninput {\n  cursor: pointer;\n}\n\n$colorNames: primary, secondary, success, info, warn, error;\n@each $colorName in $colorNames {\n  .color-#{$colorName} {\n    color: var(--color-#{$colorName});\n    background-color: var(--color-#{$colorName}-complement);\n  }\n  .color-#{$colorName}-complement {\n    color: var(--color-#{$colorName}-complement);\n    background-color: var(--color-#{$colorName});\n  }\n\n  td.#{$colorName} {\n    background-color: var(--color-#{$colorName});\n\n    span {\n      color: var(--color-#{$colorName}-complement);\n    }\n  }\n  span.#{$colorName}-black {\n    color: var(--color-#{$colorName});\n    background-color: black;\n    padding: 0.5em;\n  }\n  span.#{$colorName}-white {\n    color: var(--color-#{$colorName});\n    background-color: white;\n    padding: 0.5em;\n  }\n  span.black-#{$colorName} {\n    color: black;\n    background-color: var(--color-#{$colorName});\n    padding: 0.5em;\n  }\n  span.white-#{$colorName} {\n    color: white;\n    background-color: var(--color-#{$colorName});\n    padding: 0.5em;\n  }\n}\n\ntd,\nth {\n  padding: 1em;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { FontAwesomeIcon } from \"@fortawesome/vue-fontawesome\";\nimport { type IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport { computed, type ComputedRef } from \"vue\";\n\ninterface Props {\n  /**\n   * Icon of the button.\n   */\n  icon?: IconDefinition | null;\n  /**\n   * Text of the button.\n   */\n  text: string;\n  /**\n   * Button type attribute.\n   */\n  type?: \"button\" | \"reset\" | \"submit\";\n  /**\n   * Optional on-click function.\n   */\n  onClick?: () => void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n  type: \"button\",\n});\n\nconst hideIcon: ComputedRef<boolean> = computed(() => !props.icon);\nconst hideText: ComputedRef<boolean> = computed(() => !props.text?.length);\n</script>\n\n<template>\n  <button :type=\"props.type\" @click=\"onClick\">\n    <FontAwesomeIcon\n      class=\"square\"\n      v-if=\"!hideIcon\"\n      :icon=\"props.icon as IconDefinition\"\n    />\n    <span v-if=\"hideIcon && hideText\">&nbsp;</span>\n    <span v-if=\"!hideText\">{{ props.text }}</span>\n  </button>\n</template>\n","export type HtmlElementSelector = {\n  element?: HTMLElement;\n  elementId?: string;\n  elementClass?: string;\n  elementTag?: string;\n};\n\nexport function getElementBySelector(\n  selector: HtmlElementSelector,\n): HTMLElement {\n  if (selector.element) return selector.element;\n  if (selector.elementId) {\n    const result = document.getElementById(selector.elementId);\n    if (result) return result;\n  }\n\n  function returnFirstOfSelectedElements(\n    selectorInfo: string,\n    result: HTMLCollectionOf<Element>,\n  ) {\n    if (result.length > 1) {\n      console.warn(\n        `Selecting the first of ${result.length} elements of ${selectorInfo}.`,\n      );\n    }\n    return result[0] as HTMLElement;\n  }\n\n  if (selector.elementClass) {\n    const result = document.getElementsByClassName(selector.elementClass);\n    if (result.length > 0) {\n      return returnFirstOfSelectedElements(\n        `class ${selector.elementClass}`,\n        result,\n      );\n    }\n  }\n  if (selector.elementTag) {\n    const result = document.getElementsByTagName(selector.elementTag);\n    if (result.length > 0) {\n      return returnFirstOfSelectedElements(\n        `tag ${selector.elementTag}`,\n        result,\n      );\n    }\n  }\n  return document.body;\n}\n\nexport function sanitizeHref(hrefValue: string): string {\n  if (/^javascript:/i.test(hrefValue)) {\n    // If the URL starts with 'javascript:', replace it with '#'\n    console.error(`Blocked a href value when sanitizing ${hrefValue}`);\n    return \"#\";\n  }\n  // Otherwise, return the original value\n  return hrefValue;\n}\n","<script setup lang=\"ts\">\nimport { type IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport ButtonWithIcon from \"./ButtonWithIcon.vue\";\nimport { sanitizeHref } from \"../../provider/html-element\";\n\ninterface Props {\n  /**\n   * Icon of the button.\n   */\n  icon?: IconDefinition | null;\n  /**\n   * Text of the button.\n   */\n  text: string;\n  /**\n   * Target address.\n   */\n  href: string;\n  /**\n   * Is the button and link disabled?\n   */\n  disabled?: boolean;\n  /**\n   * Whether the target address will be open in a new browser tab or the same one.\n   */\n  openInNewTab?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n  disabled: false,\n  openInNewTab: false,\n});\n</script>\n\n<template>\n  <a\n    class=\"button-wrapper\"\n    :class=\"{ disabled: props.disabled }\"\n    :href=\"sanitizeHref(props.href)\"\n    :target=\"props.openInNewTab ? '_blank' : undefined\"\n    :rel=\"props.openInNewTab ? 'noreferrer noopener' : undefined\"\n  >\n    <ButtonWithIcon\n      :icon=\"props.icon\"\n      :text=\"props.text\"\n      :disabled=\"props.disabled\"\n    />\n  </a>\n</template>\n\n<style lang=\"scss\" scoped>\na.button-wrapper {\n  text-decoration: none;\n  display: inline-block;\n}\n\na.disabled {\n  pointer-events: unset;\n\n  &:hover {\n    cursor: not-allowed;\n  }\n}\n</style>\n","import StatusBox from \"../component/StatusBox.vue\";\nimport { defineStore } from \"pinia\";\nimport { h, type VNode } from \"vue\";\nimport { type StatusBoxFlavorName } from \"./status-box\";\nimport { getPseudoRandomString } from \"./randomness\";\n\ntype StatusBoxProps = InstanceType<typeof StatusBox>[\"$props\"];\nexport type ChildrenType = string | string[] | VNode | VNode[];\ntype Interval = ReturnType<typeof setInterval>;\n\nfunction renderChildren(children?: ChildrenType): VNode[] {\n  if (!children) return [];\n  if (typeof children === \"string\") {\n    return [h(\"p\", {}, children)];\n  }\n  if (Array.isArray(children)) {\n    if (typeof children[0] === \"string\") {\n      if (children.every((child) => typeof child === \"string\")) {\n        return children.map((child) => h(\"p\", {}, child));\n      }\n      throw new Error(\n        \"Some of the elements of this array are strings and some are not.\",\n      );\n    }\n    return children as VNode[];\n  }\n  return [children as VNode];\n}\n\ntype Notification = {\n  statusBoxProps: StatusBoxProps;\n  children: VNode[];\n  interval: Interval;\n  maxTimeMilliSeconds: number;\n  remainingTimeMilliSeconds: number;\n  isGone: boolean;\n};\ntype NotificationsList = { [key: string]: Notification };\n\nfunction getLogItems(\n  props: StatusBoxProps,\n  children: ChildrenType,\n): [string, ChildrenType, string, StatusBoxProps] {\n  const flavor = props.boxFlavorName;\n  const capitalisedFlavor = `${flavor.charAt(0).toUpperCase()}${flavor.slice(1).toLowerCase()}`;\n  return [\n    `${capitalisedFlavor} notification:\\n${props.headlineText}\\n`,\n    children,\n    \"\\n\",\n    props,\n  ];\n}\n\nexport const OPACITY_STEP_DURATION_MS = 500;\nexport const FADE_OUT_DURATION_MS = 5 * 1000;\nexport const REMOVE_IN_MS = 10 * 1000;\nexport const HEIGHT_FADE_DURATION_MS = 500;\n\nexport const useDemessifierGuiNotificationsList = defineStore({\n  id: \"demessifier-gui:notifications-list\",\n  state: () => {\n    return {\n      notificationsList: {} as NotificationsList,\n    };\n  },\n  actions: {\n    addNewNotification(\n      boxFlavorName: StatusBoxFlavorName,\n      headlineText: string,\n      children: ChildrenType,\n      removeInMilliSeconds: number | false = REMOVE_IN_MS,\n    ): string {\n      const props: StatusBoxProps = {\n        boxFlavorName,\n        headlineText,\n        canBePinned: removeInMilliSeconds !== false,\n        canBeClosed: true,\n      };\n      const notificationId = getPseudoRandomString(32);\n\n      switch (props.boxFlavorName) {\n        case \"warn\":\n          console.warn(...getLogItems(props, children));\n          break;\n        case \"error\":\n          console.error(...getLogItems(props, children));\n          break;\n      }\n      const interval = setInterval(() => {\n        const notification = this.notificationsList[notificationId];\n        if (!notification) {\n          // notification already removed, but the interval is still ticking\n          clearInterval(interval);\n          return;\n        }\n        if (notification.remainingTimeMilliSeconds > 0) {\n          notification.remainingTimeMilliSeconds -= OPACITY_STEP_DURATION_MS;\n          return;\n        }\n        this.removeNotification(notificationId);\n      }, OPACITY_STEP_DURATION_MS);\n\n      const maxTimeMilliSeconds =\n        removeInMilliSeconds === false\n          ? Infinity\n          : Math.max(removeInMilliSeconds, 0);\n      this.notificationsList[notificationId] = {\n        statusBoxProps: props,\n        children: renderChildren(children),\n        interval: interval,\n        maxTimeMilliSeconds: maxTimeMilliSeconds,\n        remainingTimeMilliSeconds: maxTimeMilliSeconds,\n        isGone: false,\n      };\n      return notificationId;\n    },\n    removeNotification(notificationId: string, ignoreMissing: boolean = true) {\n      if (\n        Object.prototype.hasOwnProperty.call(\n          this.notificationsList,\n          notificationId,\n        )\n      ) {\n        const toBeDeleted = this.notificationsList[notificationId];\n        if (!toBeDeleted) return null;\n        clearInterval(toBeDeleted.interval);\n        toBeDeleted.isGone = true;\n        setTimeout(() => {\n          delete this.notificationsList[notificationId];\n        }, HEIGHT_FADE_DURATION_MS);\n        return;\n      }\n      if (ignoreMissing) return;\n      throw new Error(\n        `Notification ID ${notificationId} is not in the notifications list.`,\n      );\n    },\n    interruptCountDown(notificationId: string) {\n      const notification = this.notificationsList[notificationId];\n      if (!notification) return;\n      if (notification.interval !== null) {\n        clearInterval(notification.interval);\n      }\n      notification.maxTimeMilliSeconds = Infinity;\n      notification.statusBoxProps.canBePinned = false;\n      this.resetTimer(notificationId);\n    },\n    resetTimer(notificationId: string) {\n      const notification = this.notificationsList[notificationId];\n      if (!notification) return;\n      notification.remainingTimeMilliSeconds = notification.maxTimeMilliSeconds;\n    },\n    getOpacityFraction(notificationId: string): number {\n      const notification = this.notificationsList[notificationId];\n      if (!notification || notification.isGone) return 0;\n      const remainingTimeMilliSeconds = notification.remainingTimeMilliSeconds;\n      if (remainingTimeMilliSeconds > FADE_OUT_DURATION_MS) return 1;\n      return (\n        remainingTimeMilliSeconds /\n        Math.min(notification.maxTimeMilliSeconds, FADE_OUT_DURATION_MS)\n      );\n    },\n    getIsGone(notificationId: string): boolean {\n      const notification = this.notificationsList[notificationId];\n      if (!notification) return true;\n      return notification.isGone;\n    },\n  },\n});\n\nexport type DemessifierGuiNotificationsList = ReturnType<\n  typeof useDemessifierGuiNotificationsList\n>;\n","<script setup lang=\"ts\">\nimport { faIcons } from \"@fortawesome/free-solid-svg-icons\";\nimport { ButtonWithIcon } from \"../global-controller\";\nimport { useDemessifierGuiNotificationsList } from \"../../provider/notification\";\n\nconst demessifierGuiNotificationsList = useDemessifierGuiNotificationsList();\n</script>\n\n<template>\n  <ButtonWithIcon\n    text=\"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci.\"\n    :icon=\"faIcons\"\n    @click=\"\n      demessifierGuiNotificationsList.addNewNotification(\n        'warn',\n        'Notification example',\n        'Example text.',\n        // 'Long example text. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris tincidunt sem sed arcu. Sed ac dolor sit amet purus malesuada congue. Etiam neque. Nullam faucibus mi quis velit. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim. Aenean placerat. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Fusce dui leo, imperdiet in, aliquam sit amet, feugiat eu, orci.',\n      )\n    \"\n  ></ButtonWithIcon>\n</template>\n","<script setup lang=\"ts\">\nimport { CSSProperties } from \"vue\";\nimport { LogoSection } from \"../../model/logo-section\";\n\ninterface Props {\n  logoSections: LogoSection[];\n}\n\nconst props = defineProps<Props>();\n\nfunction getSvgMaskStyle(svgMask?: string): CSSProperties | undefined {\n  if (!svgMask) {\n    console.warn(\"No SVG mask specified in the logo component.\");\n    return undefined;\n  }\n  const urlSvgMask = `url(\"${svgMask}\")`; // use double quotes to work with both path (/src/graphics/logo.svg) and data: (data:image/svg+xml,%3c?xml...)\n  return {\n    \"-webkit-mask-image\": urlSvgMask,\n    \"mask-image\": urlSvgMask,\n  };\n}\n\nfunction getStyle(component: LogoSection): CSSProperties | undefined {\n  switch (component.logoSectionType) {\n    case \"svg-mask-square\":\n      return getSvgMaskStyle(component.logoSectionSvgMask);\n    default:\n      return undefined;\n  }\n}\n</script>\n\n<template>\n  <div class=\"logo-wrapper\">\n    <div\n      v-for=\"component in props.logoSections\"\n      :key=\"JSON.stringify(component)\"\n      :class=\"component.logoSectionType\"\n      :style=\"getStyle(component)\"\n    >\n      {{\n        component.logoSectionType.startsWith(\"text-\")\n          ? component.logoSectionText\n          : \"\"\n      }}\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.logo-wrapper {\n  display: flex;\n  flex-direction: row;\n  flex-wrap: nowrap;\n  align-items: center;\n  background-color: var(--color-primary);\n  height: 100%;\n  white-space: nowrap;\n  overflow: hidden;\n\n  $margin: 15px;\n  margin-right: $margin;\n\n  & > * {\n    margin-left: $margin;\n  }\n\n  & > .svg-mask-square {\n    height: 100%;\n    aspect-ratio: 1 / 1;\n    background-color: var(--color-primary-complement);\n    -webkit-mask-size: contain;\n    mask-size: contain;\n    -webkit-mask-repeat: no-repeat;\n    mask-repeat: no-repeat;\n    -webkit-mask-position-x: center;\n    mask-position: center;\n  }\n\n  & > .text-title {\n    //font-family: ;\n  }\n\n  & > .text-subtitle {\n    font-size: 0.5em;\n  }\n}\n</style>\n","import {\n  faCircleHalfStroke,\n  faIcons,\n  faLink,\n  faPalette,\n  faTable,\n} from \"@fortawesome/free-solid-svg-icons\";\nimport { type IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport ColorSchemeSwitch from \"../component/global-controller/ColorSchemeSwitch.vue\";\nimport StatusBox from \"../component/StatusBox.vue\";\nimport ColorPalette from \"../component/global-controller/ColorPicker.vue\";\nimport ButtonWithIconShowcase from \"../component/layout/ButtonWithIconShowcase.vue\";\nimport { ButtonWithIconLink } from \"../component\";\n\nexport type Path = `/${string}`;\nexport type PathsList = { [key: string]: Path };\n\nconst clientPaths: PathsList = {\n  _: \"/\",\n  scheme: \"/color-scheme-switch\",\n  status: \"/status-box\",\n  iconButton: \"/button-with-icon\",\n  iconButtonLink: \"/button-with-icon-link\",\n};\n\ntype Keys = keyof typeof clientPaths;\nexport type ClientPath = (typeof clientPaths)[Keys];\n\nexport type MenuItemComponentDefinition = new (...args: any[]) => {\n  $props: any;\n};\n\nexport type MenuItem<C extends MenuItemComponentDefinition> = {\n  name: string;\n  component: () => Promise<C>; // using this should cause generating separate chunks and lazy loading them: component: () => import('../views/ExampleView.vue')\n  componentProps: InstanceType<C>[\"$props\"];\n  path: ClientPath;\n  title: string;\n  fa: IconDefinition;\n  metaTitle: string;\n};\n\nexport type MenuItemAny = MenuItem<MenuItemComponentDefinition>;\n\nconst MENU_COLORS: MenuItem<typeof ColorPalette> = {\n  name: \"ColorPalette\",\n  component: async () => ColorPalette,\n  componentProps: {},\n  path: clientPaths._,\n  title: \"ColorPalette\",\n  fa: faPalette,\n  metaTitle: \"ColorPalette\",\n};\n\nconst MENU_SCHEME: MenuItem<typeof ColorSchemeSwitch> = {\n  name: \"ColorSchemeSwitch\",\n  component: async () => ColorSchemeSwitch,\n  componentProps: {},\n  path: clientPaths.scheme,\n  title: \"ColorSchemeSwitch\",\n  fa: faCircleHalfStroke,\n  metaTitle: \"ColorSchemeSwitch\",\n};\n\nconst MENU_STATUS: MenuItem<typeof StatusBox> = {\n  name: \"StatusBox\",\n  component: async () => StatusBox,\n  componentProps: {\n    headlineText: \"StatusBox\",\n    boxFlavorName: \"success\",\n  },\n  path: clientPaths.status,\n  title: \"StatusBox\",\n  fa: faTable,\n  metaTitle: \"StatusBox\",\n};\n\nconst MENU_ICON_BUTTON: MenuItem<typeof ButtonWithIconShowcase> = {\n  name: \"ButtonWithIcon\",\n  component: async () => ButtonWithIconShowcase,\n  componentProps: {} as InstanceType<typeof ButtonWithIconShowcase>[\"$props\"],\n  path: clientPaths.iconButton,\n  title: \"ButtonWithIcon\",\n  fa: faIcons,\n  metaTitle: \"ButtonWithIcon\",\n};\n\nconst MENU_ICON_BUTTON_LINK: MenuItem<typeof ButtonWithIconLink> = {\n  name: \"ButtonWithIconLink\",\n  component: async () => ButtonWithIconLink,\n  componentProps: {\n    icon: faLink,\n    text: \"I'm a link, but I look like a button\",\n    href: \"#\",\n    openInNewTab: true,\n  } as InstanceType<typeof ButtonWithIconLink>[\"$props\"],\n  path: clientPaths.iconButtonLink,\n  title: \"ButtonWithIconLink\",\n  fa: faLink,\n  metaTitle: \"ButtonWithIcon\",\n};\n\nexport const menuExample: MenuItemAny[] = [\n  MENU_COLORS,\n  MENU_SCHEME,\n  MENU_STATUS,\n  MENU_ICON_BUTTON,\n  MENU_ICON_BUTTON_LINK,\n];\n","export default \"data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'%20standalone='no'?%3e%3c!--%20Created%20with%20Inkscape%20(http://www.inkscape.org/)%20--%3e%3csvg%20width='45.980461mm'%20height='77.69352mm'%20viewBox='0%200%2045.980461%2077.69352'%20version='1.1'%20id='svg1'%20xml:space='preserve'%20inkscape:version='1.3.1%20(91b66b0783,%202023-11-16)'%20sodipodi:docname='sbrul-shad-v1.svg'%20xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape'%20xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:svg='http://www.w3.org/2000/svg'%3e%3csodipodi:namedview%20id='namedview1'%20pagecolor='%23505050'%20bordercolor='%23ffffff'%20borderopacity='1'%20inkscape:showpageshadow='0'%20inkscape:pageopacity='0'%20inkscape:pagecheckerboard='1'%20inkscape:deskcolor='%23505050'%20inkscape:document-units='mm'%20inkscape:zoom='2.9757807'%20inkscape:cx='174.07197'%20inkscape:cy='165.50279'%20inkscape:window-width='2560'%20inkscape:window-height='1377'%20inkscape:window-x='1192'%20inkscape:window-y='193'%20inkscape:window-maximized='1'%20inkscape:current-layer='layer1'%20/%3e%3cdefs%20id='defs1'%20/%3e%3cg%20inkscape:label='Layer%201'%20inkscape:groupmode='layer'%20id='layer1'%20transform='translate(-44.263168,-72.632443)'%3e%3cpath%20style='fill:%23000000;stroke:%23000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1'%20d='m%2044.367209,91.846345%20c%2017.638073,-22.45833%2025.69175,-15.11968%2025.696037,-9.246629%200.0043,5.873052%207.542088,0.923173%2019.382468,-9.869503%20-19.723465,30.018047%20-25.992041,15.713299%20-25.962375,9.869257%200.02967,-5.844042%20-19.11613,9.246875%20-19.11613,9.246875%20z'%20id='path1'%20sodipodi:nodetypes='czczc'%20/%3e%3cpath%20style='fill:%23000000;stroke:%23000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1'%20d='m%2044.722856,97.092166%20c%2016.613917,0.574486%2018.204814,2.975824%2021.516763,8.891224%203.934335,-5.64319%207.046028,-8.379127%2023.295007,-8.713398%20-5.801257,-5.224445%20-14.763908,-5.29217%20-22.672622,3.289748%20-7.019591,-8.489232%20-14.74676,-8.309847%20-22.139148,-3.467574%20z'%20id='path2'%20sodipodi:nodetypes='ccccc'%20/%3e%3cpath%20style='fill:%23000000;stroke:%23000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1'%20d='m%2045.094943,112.55073%20c%2016.613917,0.57449%2018.204814,2.97583%2021.516763,8.89123%203.934335,-5.64319%207.046028,-8.37913%2023.295007,-8.7134%20-5.801257,-5.22445%20-14.763908,-5.29218%20-22.672622,3.28975%20-7.019591,-8.48924%20-14.74676,-8.30985%20-22.139148,-3.46758%20z'%20id='path2-2'%20sodipodi:nodetypes='ccccc'%20/%3e%3cpath%20style='fill:%23000000;stroke:%23000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1'%20d='m%2060.193586,124.56605%20c%204.598079,3.30005%207.723822,3.46245%2013.070099,-0.35565%20-2.566913,5.51769%20-2.927258,21.14038%20-5.690383,25.78455%20-1.340529,-4.69161%20-4.153518,-20.90467%20-7.379716,-25.4289%20z'%20id='path3'%20sodipodi:nodetypes='cccc'%20/%3e%3c/g%3e%3c/svg%3e\"","import TheDemessifierLogoSvg from \"../graphics/sbrul-shad-svg-v1.svg\";\n\nexport type LogoSection = {\n  logoSectionType: \"text-title\" | \"text-subtitle\" | \"svg-mask-square\";\n  logoSectionText?: string;\n  logoSectionSvgMask?: string;\n};\n\nexport const headerLogoExample: LogoSection[] = [\n  {\n    logoSectionType: \"svg-mask-square\",\n    logoSectionSvgMask: TheDemessifierLogoSvg,\n  },\n  {\n    logoSectionType: \"text-title\",\n    logoSectionText: \"My Demessifier App\",\n  },\n];\n\nexport { TheDemessifierLogoSvg };\n","/**\n * Returns all possible pairs from the given array.\n * [1, 2, 3] -> [[1,2], [1,3], [2,3]]\n * @param arr\n */\nexport function getPairs<T>(arr: T[]): T[][] {\n  return arr.map((v, i) => arr.slice(i + 1).map((w) => [v, w])).flat();\n}\n","let i = 5;\n\n// background\n\nexport const MAIN_CONTENT = 100 * i++;\n\nexport const NOTIFICATIONS = 100 * i++;\n\nexport const LEFT_MENU_BACKDROP = 100 * i++;\nexport const LEFT_MENU = 100 * i++;\n\nexport const RIGHT_MENU_BACKDROP = 100 * i++;\nexport const RIGHT_MENU = 100 * i++;\n\nexport const HEADER = 100 * i++;\n\n// foreground\n","<script setup lang=\"ts\">\nimport { StatusBox } from \"../index\";\nimport {\n  HEIGHT_FADE_DURATION_MS,\n  OPACITY_STEP_DURATION_MS,\n  useDemessifierGuiNotificationsList,\n} from \"../../provider/notification\";\nimport { type CSSStyleDeclarationSubset } from \"../../provider/css\";\n\ntype StatusBoxProps = InstanceType<typeof StatusBox>[\"$props\"];\nconst demessifierGuiNotificationsList = useDemessifierGuiNotificationsList();\n\nfunction getStyle(id: string): CSSStyleDeclarationSubset {\n  const isGone = demessifierGuiNotificationsList.getIsGone(id);\n  return {\n    opacity: `${demessifierGuiNotificationsList.getOpacityFraction(id)}`,\n    transition: `opacity ${OPACITY_STEP_DURATION_MS}ms linear, max-height ${HEIGHT_FADE_DURATION_MS}ms linear`,\n    maxHeight: isGone ? \"0\" : \"100rem\",\n    pointerEvents: isGone ? \"none\" : \"auto\",\n  };\n}\n</script>\n\n<template>\n  <div id=\"notifications-backdrop\">\n    <StatusBox\n      v-for=\"(\n        notification, id\n      ) in demessifierGuiNotificationsList.notificationsList\"\n      :key=\"id\"\n      v-bind=\"notification.statusBoxProps as StatusBoxProps\"\n      @close-status-box=\"\n        () => demessifierGuiNotificationsList.removeNotification(id as string)\n      \"\n      @pin-status-box=\"\n        () => demessifierGuiNotificationsList.interruptCountDown(id as string)\n      \"\n      @mousemove=\"demessifierGuiNotificationsList.resetTimer(id as string)\"\n      :style=\"getStyle(id as string)\"\n    >\n      <component\n        v-for=\"child in notification.children\"\n        :key=\"child\"\n        :is=\"child\"\n      />\n    </StatusBox>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n#notifications-backdrop {\n  position: absolute;\n  top: 0;\n  right: 1em;\n\n  display: flex;\n  flex-direction: column;\n  align-items: flex-end;\n  align-content: flex-end;\n  justify-content: flex-start;\n\n  pointer-events: none;\n\n  & > * {\n    margin: 1em;\n    pointer-events: auto;\n    border-radius: 0.5rem;\n    box-shadow: 0 0 1em 0.5em var(--default-bg-color);\n\n    &.full {\n      background-color: var(--default-bg-color);\n    }\n  }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref } from \"vue\";\nimport {\n  type ColorPalette,\n  setColors,\n  setDefaultColors,\n} from \"./provider/color-palette\";\nimport * as Z_INDEX from \"./provider/z-index\";\nimport MenuLeft from \"./component/layout/MenuLeft.vue\";\nimport { type MenuItemAny } from \"./provider/menu\";\nimport MenuTopRight from \"./component/layout/MenuTopRight.vue\";\nimport MainHeaderLogo from \"./component/layout/MainHeaderLogo.vue\";\nimport { FontAwesomeIcon } from \"@fortawesome/vue-fontawesome\";\nimport { faBars, faChevronDown } from \"@fortawesome/free-solid-svg-icons\";\nimport NotificationsArea from \"./component/layout/NotificationsArea.vue\";\nimport { type LogoSection } from \"./model/logo-section\";\n\n// window size for responsiveness\nconst windowSize = ref(window.innerWidth);\nconst eventListenerType = \"resize\";\nconst resizeEventListener = () => {\n  const origCompactView = compactView.value;\n  windowSize.value = window.innerWidth;\n  const newCompactView = compactView.value;\n  if (origCompactView !== newCompactView) {\n    leftMenuVisible.value = !compactView.value;\n  }\n};\nonMounted(() =>\n  window.addEventListener(eventListenerType, resizeEventListener),\n);\nonBeforeUnmount(() =>\n  window.removeEventListener(eventListenerType, resizeEventListener),\n);\n\nconst compactView = computed(() => windowSize.value < 1024);\n\n// view toggles\nconst leftMenuVisible = ref(!compactView.value);\nconst rightMenuVisible = ref(false);\n\nfunction toggleLeftMenu() {\n  leftMenuVisible.value = !leftMenuVisible.value;\n}\n\nfunction toggleRightMenu() {\n  rightMenuVisible.value = !rightMenuVisible.value;\n}\n\nfunction hideLeftMenu() {\n  leftMenuVisible.value = false;\n}\n\nfunction hideRightMenu() {\n  rightMenuVisible.value = false;\n}\n\nfunction hideLeftMenuIfCompact() {\n  if (!compactView.value) return;\n  hideLeftMenu();\n}\n\nsetDefaultColors();\n\ninterface Props {\n  mainHeaderLogo: LogoSection[];\n  menu: MenuItemAny[];\n  colorPalette: ColorPalette;\n}\n\nconst props = defineProps<Props>();\n\nsetColors(props.colorPalette);\n</script>\n\n<template>\n  <div class=\"layout\">\n    <header :style=\"`z-index: ${Z_INDEX.HEADER}`\">\n      <span class=\"icon-button\" @click=\"toggleLeftMenu\">\n        <FontAwesomeIcon\n          :icon=\"faBars\"\n          :title=\"`${leftMenuVisible ? 'Hide' : 'Show'} main menu`\"\n        />\n      </span>\n      <div class=\"logo\">\n        <MainHeaderLogo v-bind=\"{ logoSections: props.mainHeaderLogo }\" />\n      </div>\n      <span class=\"icon-button\" @click=\"toggleRightMenu\">\n        <FontAwesomeIcon\n          :icon=\"faChevronDown\"\n          :title=\"`${rightMenuVisible ? 'Hide' : 'Show'} quick menu`\"\n        />\n      </span>\n    </header>\n    <div\n      class=\"backdrop right-menu-backdrop\"\n      :class=\"{ hidden: !rightMenuVisible }\"\n      :style=\"`z-index: ${Z_INDEX.RIGHT_MENU_BACKDROP}`\"\n      @click=\"hideRightMenu\"\n    />\n    <MenuTopRight\n      class=\"menu-content right-menu-content\"\n      :class=\"{ hidden: !rightMenuVisible, compact: compactView }\"\n      :style=\"`z-index: ${Z_INDEX.RIGHT_MENU}`\"\n    />\n    <div class=\"left-and-main\" :class=\"{ compact: compactView }\">\n      <div\n        class=\"backdrop left-menu-backdrop\"\n        :class=\"{\n          hidden: !(leftMenuVisible && compactView),\n          compact: compactView,\n        }\"\n        :style=\"`z-index: ${Z_INDEX.LEFT_MENU_BACKDROP}`\"\n        @click=\"hideLeftMenu\"\n      />\n      <nav\n        class=\"menu-content left-menu-content\"\n        :class=\"{ hidden: !leftMenuVisible, compact: compactView }\"\n        :style=\"`z-index: ${Z_INDEX.LEFT_MENU}`\"\n        @click=\"hideLeftMenuIfCompact\"\n      >\n        <MenuLeft :menu-items=\"menu\" />\n      </nav>\n      <div class=\"main-and-notifications\">\n        <NotificationsArea :style=\"`z-index: ${Z_INDEX.NOTIFICATIONS}`\" />\n        <main :style=\"`z-index: ${Z_INDEX.MAIN_CONTENT}`\">\n          <router-view v-slot=\"{ Component }\">\n            <transition name=\"fade\" mode=\"out-in\" appear>\n              <component :is=\"Component\" />\n            </transition>\n          </router-view>\n        </main>\n      </div>\n    </div>\n    <!-- <footer> </footer> -->\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.layout {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  align-items: center;\n  height: 100vh;\n  position: relative;\n}\n\n$headerHeight: 3rem;\n$headerBorderBottom: 1px;\n\nheader {\n  display: flex;\n  flex-direction: row;\n  flex-wrap: nowrap;\n  align-items: center;\n  height: $headerHeight;\n  width: 100%;\n  position: sticky;\n  top: 0;\n  border-bottom: var(--color-secondary) solid $headerBorderBottom;\n  background-color: var(--color-primary);\n  color: var(--color-primary-complement);\n\n  .icon-button {\n    aspect-ratio: 1 / 1;\n    cursor: pointer;\n\n    &:first-child {\n      border-right: var(--color-secondary) solid 1px;\n    }\n\n    &:last-child {\n      border-left: var(--color-secondary) solid 1px;\n    }\n\n    svg {\n      $padding: 25%;\n      height: calc(100% - 2 * $padding);\n      padding: $padding;\n    }\n\n    &:hover {\n      background-color: var(--color-secondary);\n      color: var(--color-secondary-complement);\n    }\n  }\n\n  .logo {\n    width: 100%;\n    height: 80%;\n    font-size: calc($headerHeight * 0.8);\n  }\n}\n\nheader > * {\n  height: 100%;\n}\n\n.menu-content,\n.backdrop {\n  transition: all 300ms ease;\n\n  &.hidden {\n    visibility: hidden;\n    opacity: 0;\n  }\n\n  &:not(.hidden) {\n    visibility: visible;\n    //opacity: 100%; // 50% for backdrop\n  }\n}\n\n.backdrop {\n  position: fixed;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  background-color: var(--color-secondary);\n  opacity: 50%;\n}\n\n.menu-content {\n  color: initial;\n  background-color: Window;\n  border: var(--color-secondary) solid;\n  max-height: calc(100vh - $headerHeight - $headerBorderBottom);\n  box-shadow: 0 0 1em 0.5em var(--color-secondary);\n\n  &.hidden {\n    transform: scaleX(0);\n  }\n\n  &:not(.hidden) {\n    transform: scaleX(1);\n  }\n\n  &.compact {\n    left: 0;\n  }\n\n  &.compact,\n  &.right-menu-content {\n    border-width: 1px 0 1px 0;\n    position: absolute;\n    top: calc($headerHeight + $headerBorderBottom);\n    right: 0;\n  }\n\n  &.left-menu-content {\n    transform-origin: left;\n    min-width: 15em;\n    white-space: nowrap;\n    overflow-x: hidden;\n    overflow-y: auto;\n\n    &:not(.compact) {\n      border-width: 0 1px 0 0;\n      box-shadow: none;\n\n      &.hidden {\n        min-width: 0;\n        width: 0;\n      }\n    }\n  }\n\n  &.right-menu-content {\n    transform-origin: right;\n    display: flex;\n    min-width: 15em;\n    flex-direction: column;\n    flex-wrap: nowrap;\n    align-items: flex-end;\n    gap: 0.5em;\n    padding: 0.5em;\n  }\n}\n\n.left-and-main {\n  height: 100%;\n  width: 100%;\n\n  &.compact {\n    display: block;\n  }\n\n  &:not(.compact) {\n    display: flex;\n    flex-direction: row;\n    flex-wrap: nowrap;\n  }\n\n  .main-and-notifications {\n    position: relative;\n    width: 100%;\n    height: calc(100vh - $headerHeight - $headerBorderBottom);\n\n    main {\n      padding: 1em;\n      box-sizing: border-box;\n      overflow: auto;\n      max-height: calc(100vh - $headerHeight - $headerBorderBottom);\n\n      .fade-enter-active,\n      .fade-leave-active {\n        transition: all 300ms ease;\n      }\n\n      .fade-enter-from,\n      .fade-leave-to {\n        opacity: 0;\n      }\n    }\n  }\n}\n</style>\n","import { createApp } from \"vue\";\nimport { createPinia } from \"pinia\";\nimport { type Router } from \"vue-router\";\nimport \"./css/default-css-variables.css\";\nimport \"./css/global.css\";\nimport \"./css/table.css\";\nimport \"./css/form.css\";\nimport { getRouterForMenu } from \"./provider/router\";\nimport { menuExample } from \"./provider/menu\";\nimport { type MenuItemAny } from \"./provider/menu\";\n\nimport {\n  ButtonWithIcon,\n  ButtonWithIconLink,\n  ColorSchemeSwitch,\n  ColorPicker,\n  StatusBox,\n} from \"./component\";\nimport * as model from \"./model\";\nimport * as provider from \"./provider\";\nimport App from \"./App.vue\";\nimport {\n  getElementBySelector,\n  type HtmlElementSelector,\n} from \"./provider/html-element\";\nimport { type LogoSection, headerLogoExample } from \"./model/logo-section\";\nimport { type ColorPalette, defaultColors } from \"./provider/color-palette\";\n\nexport {\n  ButtonWithIcon,\n  ButtonWithIconLink,\n  ColorSchemeSwitch,\n  ColorPicker,\n  StatusBox,\n  model,\n  provider,\n};\n\nconst routerExample = getRouterForMenu(menuExample);\n\nexport const pinia = createPinia();\n\nexport function mountApp(\n  targetElementSelector: HtmlElementSelector = { element: document.body },\n  router: Router = routerExample,\n  menu: MenuItemAny[] = menuExample,\n  appPlugins: any[] = [],\n  headerLogoProps: LogoSection[] = headerLogoExample,\n  colorPalette: ColorPalette = defaultColors,\n): ReturnType<typeof createApp> {\n  const mountToElement = getElementBySelector(targetElementSelector);\n  const app = createApp(App, {\n    mainHeaderLogo: headerLogoProps,\n    menu: menu,\n    colorPalette: colorPalette,\n  });\n  app.use(pinia);\n  app.use(router);\n  for (const plugin of appPlugins) {\n    app.use(plugin);\n  }\n  router.isReady().then(() => {\n    app.mount(mountToElement);\n  });\n  return app;\n}\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_createTextVNode","_createVNode","_withCtx","menu","router","createRouter","createWebHistory","i","colorPalette","colorScheme","defineStore","faCircleCheck","faCircleInfo","faCircleExclamation","faTriangleExclamation","computed","ref","h","notification","faPalette","faCircleHalfStroke","faTable","ButtonWithIconShowcase","faIcons","faLink","onMounted","onBeforeUnmount","createPinia","createApp"],"mappings":"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"}