{"version":3,"file":"app.js","sources":["../../../src/gui/mixins.ts","../../../src/gui/HtmlUtils.ts","../../../src/gui/animation/Animations.ts","../../../src/gui/base/Overlay.ts","../../../src/gui/AriaUtils.ts","../../../src/misc/WhitelabelCustomizations.ts","../../../src/misc/RouteChange.ts","../../../src/gui/theme.ts","../../../src/gui/base/Flash.ts","../../../src/misc/ClientDetector.ts","../../libs/mithril.js","../../../src/misc/LanguageViewModel.ts","../../../src/gui/animation/Easing.ts","../../../src/gui/base/Color.ts","../../../src/misc/DeviceConfig.ts","../../../src/gui/base/Logo.ts","../../../src/gui/builtinThemes.ts","../../../src/gui/ThemeController.ts","../../../src/misc/KeyManager.ts","../../../src/misc/WindowFacade.ts","../../../src/gui/base/Modal.ts","../../../src/misc/Log.ts","../../../src/gui/size.ts","../../../src/gui/styles.ts","../../../src/RootView.ts","../../../src/misc/ErrorHandler.ts","../../../src/serviceworker/ServiceWorkerClient.ts","../../../src/app.ts","../../../src/ApplicationPaths.ts","../../../src/api/main/LoginController.ts"],"sourcesContent":["import { px } from \"./size\"\nimport { assertMainOrNodeBoot } from \"../api/common/Env\"\n\nassertMainOrNodeBoot()\nexport const noselect = {\n\t_webkit_touch_callout: \"none\",\n\n\t/* iOS Safari */\n\t_webkit_user_select: \"none\",\n\n\t/* Chrome/Safari/Opera */\n\t_khtml_user_select: \"none\",\n\n\t/* Konqueror */\n\t_moz_user_select: \"none\",\n\n\t/* Firefox */\n\t_ms_user_select: \"none\",\n\n\t/* IE/Edge */\n\tuser_select: \"none\",\n\t/* non_prefixed version, currently not supported by any browser */\n}\n\nexport function position_absolute(\n\ttop: number | null,\n\tright: number | null,\n\tbottom: number | null,\n\tleft: number | null,\n): {\n\tbottom: number | string\n\tleft: number | string\n\tposition: string\n\tright: number | string\n\ttop: number | string\n} {\n\treturn {\n\t\tposition: \"absolute\",\n\t\ttop: positionValue(top),\n\t\tright: positionValue(right),\n\t\tbottom: positionValue(bottom),\n\t\tleft: positionValue(left),\n\t}\n}\n\nexport function positionValue(value: number | null): number | string {\n\tif (value) {\n\t\treturn px(value)\n\t} else if (value === 0) {\n\t\treturn 0\n\t} else {\n\t\treturn \"unset\"\n\t}\n}\n\nexport function flex(args: string): {\n\t_ms_flex: string\n\t_webkit_box_flex: string\n\t_webkit_flex: string\n\tflex: string\n} {\n\treturn {\n\t\t_webkit_box_flex: args,\n\t\t_webkit_flex: args,\n\t\t_ms_flex: args,\n\t\tflex: args,\n\t}\n}\n\n// We apply backface_visibility on all animated elements to increase animation performance on mobile devices\nexport const backface_fix = {\n\t_webkit_backface_visibility: \"hidden\",\n\tbackface_visibility: \"hidden\",\n}\n","import { assertNotNull, downcast } from \"@tutao/tutanota-utils\"\nimport { assertMainOrNodeBoot } from \"../api/common/Env\"\n\nassertMainOrNodeBoot()\n\nexport function applySafeAreaInsetMarginLR(element: HTMLElement) {\n\telement.style.marginRight = \"env(safe-area-inset-right)\"\n\telement.style.marginLeft = \"env(safe-area-inset-left)\"\n}\n\nexport function getSafeAreaInsetLeft(): string {\n\treturn window.orientation === 90 ? \"env(safe-area-inset-left)\" : \"\"\n}\n\nexport function getSafeAreaInsetRight(): string {\n\treturn window.orientation === -90 ? \"env(safe-area-inset-right)\" : \"\"\n}\n\n/**\n * Only used for iOS. We need to go through CSS variable because getting env() directly does not work.\n * see https://benfrain.com/how-to-get-the-value-of-phone-notches-environment-variables-env-in-javascript-from-css/\n * We need to adjust bottom position because of the home button on iOS which shifts everything up.\n */\nexport function getSafeAreaInsetTop(): number {\n\tconst bottomInsetString = getComputedStyle(assertNotNull(document?.body)).getPropertyValue(\"--safe-area-inset-top\")\n\treturn bottomInsetString ? parseInt(bottomInsetString.slice(0, -2)) : 0\n}\n\n/**\n * Only used for iOS. We need to go through CSS variable because getting env() directly does not work.\n * see https://benfrain.com/how-to-get-the-value-of-phone-notches-environment-variables-env-in-javascript-from-css/\n * We need to adjust bottom position because of the home button on iOS which shifts everything up.\n */\nexport function getSafeAreaInsetBottom(): number {\n\tconst bottomInsetString = getComputedStyle(assertNotNull(document?.body)).getPropertyValue(\"--safe-area-inset-bottom\")\n\treturn bottomInsetString ? parseInt(bottomInsetString.slice(0, -2)) : 0\n}\n\nexport function stringifyFragment(fragment: DocumentFragment): string {\n\tlet div = document.createElement(\"div\")\n\tdiv.appendChild(fragment)\n\treturn div.innerHTML\n}\n","import type { EasingFunction } from \"./Easing\"\nimport { ease } from \"./Easing\"\nimport { downcast } from \"@tutao/tutanota-utils\"\nimport { hexToRgb } from \"../base/Color\"\nimport { assertMainOrNodeBoot } from \"../../api/common/Env\"\n\nassertMainOrNodeBoot()\n\nexport interface DomMutation {\n\tupdateDom(target: HTMLElement, percent: number, easing: EasingFunction): void\n\n\twillChange(): string\n}\n\ninterface DomTransform extends DomMutation {\n\tchain(type: TransformEnum, begin: number, end: number): DomTransform\n}\n\nexport const enum AlphaEnum {\n\tBackgroundColor = \"backgroundColor\",\n\tColor = \"color\",\n}\n\nexport const enum TransformEnum {\n\t/** shift the element in left-right direction. begin and end denote the target offset from the \"natural\" position */\n\tTranslateX = \"translateX\",\n\t/** shift the element in top-bottom direction. begin and end denote the target offset from the \"natural\" position */\n\tTranslateY = \"translateY\",\n\tRotateY = \"rotateY\",\n\tRotateZ = \"rotateZ\",\n\t/** scale the element both horizontally and vertically. begin and end denote the desired scale in 0-1 range. */\n\tScale = \"scale\",\n}\n\ntype TransformValues = Record<\n\tTransformEnum,\n\t{\n\t\tbegin: number\n\t\tend: number\n\t}\n>\nexport const DefaultAnimationTime = 200 // ms\n\nconst InitializedOptions = {\n\tstagger: 0,\n\tdelay: 0,\n\teasing: ease.linear,\n\tduration: DefaultAnimationTime,\n}\nexport type AnimationPromise = {\n\tanimations?: Array<Animation>\n} & Promise<unknown>\n\nclass Animations {\n\tactiveAnimations: Animation[]\n\t_animate: (...args: Array<any>) => any\n\n\tconstructor() {\n\t\tthis.activeAnimations = []\n\n\t\tthis._animate = () => {\n\t\t\tlet finished: Animation[] = []\n\t\t\tlet now = window.performance.now()\n\n\t\t\tfor (let animation of this.activeAnimations) {\n\t\t\t\tanimation.animateFrame(now)\n\n\t\t\t\tif (animation.isFinished()) {\n\t\t\t\t\tfinished.push(animation)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (let animation of finished) {\n\t\t\t\tthis.activeAnimations.splice(this.activeAnimations.indexOf(animation), 1)\n\n\t\t\t\tif (animation.resolve) {\n\t\t\t\t\tanimation.resolve()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.activeAnimations.length > 0) {\n\t\t\t\twindow.requestAnimationFrame(this._animate)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Adds an animation that should be executed immediately. Returns a promise that resolves after the animation is complete.\n\t */\n\tadd(\n\t\ttargets: HTMLElement | HTMLElement[] | HTMLCollection,\n\t\tmutations: DomMutation | DomMutation[],\n\t\toptions?: {\n\t\t\tstagger?: number\n\t\t\tdelay?: number\n\t\t\teasing?: EasingFunction\n\t\t\tduration?: number\n\t\t},\n\t): AnimationPromise {\n\t\tconst targetsArray: Array<HTMLElement> = targets instanceof HTMLElement ? [targets] : (Array.from(targets) as Array<HTMLElement>)\n\n\t\tlet targetMutations: DomMutation[]\n\n\t\tif (!(mutations instanceof Array)) {\n\t\t\ttargetMutations = [mutations]\n\t\t} else {\n\t\t\ttargetMutations = mutations\n\t\t}\n\n\t\tlet verifiedOptions = Animations.verifiyOptions(options)\n\t\tconst willChange = targetMutations\n\t\t\t.map((mutation) => mutation.willChange())\n\t\t\t.filter((willChange) => willChange.length)\n\t\t\t.join(\" \")\n\t\ttargetsArray.forEach((t) => (t.style.willChange = willChange))\n\t\tconst animations: Animation[] = []\n\t\tconst promise = new Promise((resolve) => {\n\t\t\tlet start = this.activeAnimations.length ? false : true\n\n\t\t\tfor (let i = 0; i < targetsArray.length; i++) {\n\t\t\t\tlet delay = verifiedOptions.delay\n\n\t\t\t\tif (verifiedOptions.stagger) {\n\t\t\t\t\tdelay += verifiedOptions.stagger * i\n\t\t\t\t}\n\n\t\t\t\tconst animation = new Animation(\n\t\t\t\t\ttargetsArray[i],\n\t\t\t\t\ttargetMutations,\n\t\t\t\t\ti === targetsArray.length - 1 ? resolve : null,\n\t\t\t\t\tdelay,\n\t\t\t\t\tverifiedOptions.easing,\n\t\t\t\t\tverifiedOptions.duration,\n\t\t\t\t)\n\t\t\t\tanimations.push(animation)\n\t\t\t\tthis.activeAnimations.push(animation)\n\t\t\t}\n\n\t\t\tif (start) {\n\t\t\t\twindow.requestAnimationFrame(this._animate)\n\t\t\t}\n\t\t})\n\t\tconst animationPromise = downcast<AnimationPromise>(promise)\n\t\tanimationPromise.animations = animations\n\t\treturn animationPromise\n\t}\n\n\tcancel(animation: Animation) {\n\t\tthis.activeAnimations.splice(this.activeAnimations.indexOf(animation), 1)\n\n\t\tif (animation.resolve) {\n\t\t\tanimation.resolve()\n\t\t}\n\t}\n\n\tstatic verifiyOptions(\n\t\toptions:\n\t\t\t| {\n\t\t\t\t\tstagger?: number\n\t\t\t\t\tdelay?: number\n\t\t\t\t\teasing?: EasingFunction\n\t\t\t  }\n\t\t\t| null\n\t\t\t| undefined,\n\t): {\n\t\tstagger: number\n\t\tdelay: number\n\t\teasing: EasingFunction\n\t\tduration: number\n\t} {\n\t\treturn Object.assign({}, InitializedOptions, options)\n\t}\n}\n\nexport class Animation {\n\ttarget: HTMLElement\n\tmutations: DomMutation[]\n\tresolve: ((...args: Array<any>) => any) | null\n\tduration: number\n\tdelay: number\n\tanimationStart: number | null\n\trunTime: number | null\n\teasing: EasingFunction\n\n\tconstructor(\n\t\ttarget: HTMLElement,\n\t\tmutations: DomMutation[],\n\t\tresolve: ((...args: Array<any>) => any) | null,\n\t\tdelay: number,\n\t\teasing: EasingFunction,\n\t\tduration: number = DefaultAnimationTime,\n\t) {\n\t\tthis.target = target\n\t\tthis.mutations = mutations\n\t\tthis.resolve = resolve\n\t\tthis.delay = delay\n\t\tthis.duration = duration\n\t\tthis.animationStart = null\n\t\tthis.runTime = null\n\t\tthis.easing = easing\n\t}\n\n\tanimateFrame(now: number) {\n\t\tif (this.animationStart == null) this.animationStart = now\n\t\tthis.runTime = Math.min(now - this.animationStart - this.delay, this.duration)\n\n\t\tif (this.runTime >= 0) {\n\t\t\tfor (let m of this.mutations) {\n\t\t\t\tm.updateDom(this.target, this.runTime / this.duration, this.easing)\n\t\t\t}\n\t\t}\n\t}\n\n\tisFinished(): boolean {\n\t\treturn this.runTime != null && this.runTime >= this.duration\n\t}\n}\n\nexport function transform(type: TransformEnum, begin: number, end: number): DomTransform {\n\tconst values = {} as TransformValues\n\n\tvalues[type] = {\n\t\tbegin,\n\t\tend,\n\t}\n\n\tlet updateDom = function (target: HTMLElement, percent: number, easing: EasingFunction): void {\n\t\ttarget.style.transform = buildTransformString(values, percent, easing)\n\t}\n\n\tconst willChange = () => \"transform\"\n\n\tlet chain = function (type: TransformEnum, begin: number, end: number) {\n\t\tvalues[type] = {\n\t\t\tbegin,\n\t\t\tend,\n\t\t}\n\t\treturn {\n\t\t\tupdateDom,\n\t\t\tchain,\n\t\t\twillChange,\n\t\t}\n\t}\n\n\treturn {\n\t\tupdateDom,\n\t\tchain,\n\t\twillChange,\n\t}\n}\n\nexport function scroll(begin: number, end: number): DomMutation {\n\treturn {\n\t\tupdateDom: function (target: HTMLElement, percent: number, easing: EasingFunction): void {\n\t\t\ttarget.scrollTop = calculateValue(percent, begin, end, easing)\n\t\t},\n\t\twillChange: () => \"\",\n\t}\n}\n\nconst TransformUnits = {\n\t[TransformEnum.TranslateX]: \"px\",\n\t[TransformEnum.TranslateY]: \"px\",\n\t[TransformEnum.RotateY]: \"deg\",\n\t[TransformEnum.RotateZ]: \"deg\",\n\t[TransformEnum.Scale]: \"\",\n}\n\nfunction buildTransformString(values: TransformValues, percent: number, easing: EasingFunction) {\n\tlet transform: string[] = []\n\tlet types: TransformEnum[] = Object.keys(TransformUnits) as any[] // the order is important (e.g. 'rotateY(45deg) translateX(10px)' leads to other results than 'translateX(10px) rotateY(45deg)'\n\n\tfor (let type of types) {\n\t\tif (values[type]) {\n\t\t\tlet value = calculateValue(percent, values[type].begin, values[type].end, easing)\n\t\t\ttransform.push(type + \"(\" + value + TransformUnits[type] + \")\")\n\t\t}\n\t}\n\n\treturn transform.join(\" \")\n}\n\n/**\n * We use the alpha channel instead of using opacity for fading colors. Opacity changes are slow on mobile devices as they\n * effect the whole tree of the dom element with changing opacity.\n *\n * See http://stackoverflow.com/a/14677373 for a more detailed explanation.\n */\nexport function alpha(type: AlphaEnum, colorHex: string, begin: number, end: number): DomMutation {\n\tlet color = hexToRgb(colorHex)\n\treturn {\n\t\tupdateDom: function (target: HTMLElement, percent: number, easing: EasingFunction): void {\n\t\t\tlet alphaChannel = calculateValue(percent, begin, end, easing)\n\n\t\t\tif (type === AlphaEnum.BackgroundColor) {\n\t\t\t\ttarget.style.backgroundColor = `rgba(${color.r}, ${color.g}, ${color.b}, ${alphaChannel})`\n\t\t\t} else if (type === AlphaEnum.Color) {\n\t\t\t\ttarget.style.color = `rgba(${color.r}, ${color.g}, ${color.b}, ${alphaChannel})`\n\t\t\t}\n\t\t},\n\t\twillChange: () => \"alpha\",\n\t}\n}\n\n/**\n * Only use on small elements. You should use Alpha for fading large backgrounds which is way faster on mobiles.\n */\nexport function opacity(begin: number, end: number, keepValue: boolean): DomMutation {\n\tlet initialOpacity: string | null = null\n\treturn {\n\t\tupdateDom: function (target: HTMLElement, percent: number, easing: EasingFunction): void {\n\t\t\tif (percent === 0 && initialOpacity === null) {\n\t\t\t\tinitialOpacity = target.style.opacity\n\t\t\t}\n\n\t\t\tlet opacity = calculateValue(percent, begin, end, easing)\n\n\t\t\tif (percent === 1 && !keepValue) {\n\t\t\t\t// on some elements the value hast to be set to the initial value because hover using opacity won't work otherwise.\n\t\t\t\ttarget.style.opacity = initialOpacity ? initialOpacity : \"\"\n\t\t\t} else {\n\t\t\t\ttarget.style.opacity = opacity + \"\"\n\t\t\t}\n\t\t},\n\t\twillChange: () => \"opacity\",\n\t}\n}\n\nexport function height(begin: number, end: number): DomMutation {\n\treturn {\n\t\tupdateDom: function (target: HTMLElement, percent: number, easing: EasingFunction): void {\n\t\t\ttarget.style.height = calculateValue(percent, begin, end, easing) + \"px\"\n\t\t},\n\t\twillChange: () => \"height\",\n\t}\n}\n\nexport function width(begin: number, end: number): DomMutation {\n\treturn {\n\t\tupdateDom: function (target: HTMLElement, percent: number, easing: EasingFunction): void {\n\t\t\ttarget.style.width = calculateValue(percent, begin, end, easing) + \"px\"\n\t\t},\n\t\twillChange: () => \"width\",\n\t}\n}\n\nexport function fontSize(begin: number, end: number): DomMutation {\n\treturn {\n\t\tupdateDom: function (target: HTMLElement, percent: number, easing: EasingFunction): void {\n\t\t\ttarget.style.fontSize = calculateValue(percent, begin, end, easing) + \"px\"\n\t\t},\n\t\twillChange: () => \"\",\n\t}\n}\n\nfunction calculateValue(percent: number, begin: number, end: number, easing: (...args: Array<any>) => any): number {\n\treturn (end - begin) * easing(percent) + begin\n}\n\nexport const animations: Animations = new Animations()\n\nexport function get(element: HTMLElement | null): HTMLElement {\n\tif (!element) throw new Error(\"tried to update a non existing element\")\n\treturn element\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { DomMutation } from \"../animation/Animations\"\nimport { animations } from \"../animation/Animations\"\nimport { ease } from \"../animation/Easing\"\nimport { LayerType } from \"../../RootView\"\nimport { remove } from \"@tutao/tutanota-utils\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { assertMainOrNodeBoot } from \"../../api/common/Env\"\n\nassertMainOrNodeBoot()\nexport type PositionRect = {\n\ttop?: string | null\n\tleft?: string | null\n\tright?: string | null\n\twidth?: string | null\n\tbottom?: string | null\n\theight?: string | null\n\tzIndex?: LayerType\n}\ntype AnimationProvider = (dom: HTMLElement) => DomMutation\ntype OverlayAttrs = {\n\tcomponent: Component\n\tposition: lazy<PositionRect>\n\tcreateAnimation?: AnimationProvider\n\tcloseAnimation?: AnimationProvider\n\tshadowClass: string\n}\n\ntype Overlay = [OverlayAttrs, HTMLElement | null, number]\nconst overlays: Array<Overlay> = []\nlet key = 0\n\nexport function displayOverlay(\n\tposition: lazy<PositionRect>,\n\tcomponent: Component,\n\tcreateAnimation?: AnimationProvider,\n\tcloseAnimation?: AnimationProvider,\n\tshadowClass: string = \"dropdown-shadow\",\n): () => Promise<void> {\n\tconst newAttrs = {\n\t\tposition,\n\t\tcomponent,\n\t\tcreateAnimation,\n\t\tcloseAnimation,\n\t\tshadowClass,\n\t}\n\tconst pair = [newAttrs, null, key++] as Overlay\n\toverlays.push(pair)\n\treturn async () => {\n\t\tconst dom = pair[1]\n\t\tconst animation =\n\t\t\tnewAttrs.closeAnimation && dom\n\t\t\t\t? animations.add(dom, newAttrs.closeAnimation(dom), {\n\t\t\t\t\t\tduration: 100,\n\t\t\t\t\t\teasing: ease.in,\n\t\t\t\t  })\n\t\t\t\t: Promise.resolve()\n\t\tawait animation\n\n\t\tif (remove(overlays, pair)) {\n\t\t\tm.redraw()\n\t\t}\n\t}\n}\n\nexport const overlay: Component = {\n\tview: (): Children =>\n\t\tm(\n\t\t\t// we want the overlays to position relative to the overlay parent\n\t\t\t// the overlay parent also should fill the root\n\t\t\t\"#overlay.fill-absolute\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\tdisplay: overlays.length > 0 ? \"\" : \"none\",\n\t\t\t\t\t\"margin-top\": \"env(safe-area-inset-top)\", // insets for iPhone X\n\t\t\t\t\t// we would need to change this if we wanted something to appear from the side\n\t\t\t\t\t\"margin-left\": \"env(safe-area-inset-left)\",\n\t\t\t\t\t\"margin-right\": \"env(safe-area-inset-right)\",\n\t\t\t\t},\n\t\t\t\t\"aria-hidden\": overlays.length === 0,\n\t\t\t},\n\t\t\toverlays.map((overlayAttrs) => {\n\t\t\t\tconst [attrs, dom, key] = overlayAttrs\n\t\t\t\tconst position = attrs.position()\n\t\t\t\treturn m(\n\t\t\t\t\t\".abs.elevated-bg.\" + attrs.shadowClass,\n\t\t\t\t\t{\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\twidth: position.width,\n\t\t\t\t\t\t\ttop: position.top,\n\t\t\t\t\t\t\tbottom: position.bottom,\n\t\t\t\t\t\t\tright: position.right,\n\t\t\t\t\t\t\tleft: position.left,\n\t\t\t\t\t\t\theight: position.height,\n\t\t\t\t\t\t\t\"z-index\": position.zIndex != null ? position.zIndex : LayerType.Overlay,\n\t\t\t\t\t\t},\n\t\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\t\tconst dom = vnode.dom as HTMLElement\n\t\t\t\t\t\t\toverlayAttrs[1] = dom\n\n\t\t\t\t\t\t\tif (attrs.createAnimation) {\n\t\t\t\t\t\t\t\tanimations.add(dom, attrs.createAnimation(dom))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonremove: () => {\n\t\t\t\t\t\t\toverlayAttrs[1] = null\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tm(attrs.component),\n\t\t\t\t)\n\t\t\t}),\n\t\t),\n}\n","import { assertMainOrNodeBoot } from \"../api/common/Env\"\n\nassertMainOrNodeBoot()\n\n/**\n * Collections of utility functions to support Accessible Rich Internet Applications (ARIA).\n *\n * https://www.w3.org/TR/wai-aria-practices/\n * https://www.w3.org/TR/wai-aria-1.1/\n * https://webaim.org/techniques/aria/\n * https://www.w3.org/TR/wai-aria-1.1/\n *\n */\nimport { TabIndex } from \"../api/common/TutanotaConstants\"\n\n// See: https://webaim.org/techniques/aria/#landmarks\nexport const enum AriaLandmarks {\n\tBanner = \"banner\",\n\tSearch = \"search\",\n\tNavigation = \"navigation\",\n\tMain = \"main\",\n\tComplementary = \"complementary\",\n\tContentinfo = \"contentinfo\",\n\tRegion = \"region\",\n}\n\nexport const enum AriaLiveRegions {\n\tAlert = \"alert\",\n\tLog = \"log\",\n\tMarquee = \"Marquee\",\n\tStatus = \"status\",\n\tTimer = \"timer\",\n}\n\nexport const enum AriaWindow {\n\tAlertDialog = \"alertdialog\",\n\tDialog = \"dialog\",\n}\n\nconst enum AriaLiveData {\n\t//default\n\tOff = \"off\",\n\t//\tIndicates that updates to the region should be presented at the next graceful opportunity\n\tPolite = \"polite\",\n\t//region has the highest priority\n\tAssertive = \"assertive\",\n}\n\nexport function liveDataAttrs(): Record<string, string> {\n\treturn {\n\t\t\"aria-live\": AriaLiveData.Polite,\n\t\t\"aria-atomic\": \"true\",\n\t}\n}\n\n/**\n * construct spreadable landmark attributes for screen readers.\n * return value includes a hide-outline class that will be overridden if the selector\n * used to construct the element contains other classes.\n */\nexport function landmarkAttrs(role: AriaLandmarks, label?: string): Record<string, string | undefined> {\n\treturn {\n\t\tclass: \"hide-outline\",\n\t\trole,\n\t\ttabindex: TabIndex.Programmatic,\n\t\t\"aria-label\": label,\n\t}\n}\n","import type { BaseThemeId, Theme } from \"../gui/theme\"\nimport type { BootstrapFeatureType } from \"../api/common/TutanotaConstants\"\nimport { assertMainOrNodeBoot } from \"../api/common/Env\"\nimport type { WhitelabelConfig } from \"../api/entities/sys/TypeRefs.js\"\n\nassertMainOrNodeBoot()\nexport type ThemeCustomizations = Partial<Theme> & {\n\tbase: BaseThemeId | null\n}\nexport type ThemeKey = keyof Theme\nexport type CustomizationKey = keyof ThemeCustomizations\n\nexport type WhitelabelCustomizations = {\n\ttheme: ThemeCustomizations | null\n\tbootstrapCustomizations: BootstrapFeatureType[]\n\tgermanLanguageCode: string\n\tregistrationDomains: string[] | null\n\timprintUrl: string | null\n\tprivacyStatementUrl: string | null\n}\n\n/**\n * window.whitelabelCustomizations is defined when the user has logged in via a whitelabel domain. index.js is rewritten to have the definition\n * this happens at WhitelabelResourceRewriter.java\n */\nexport function getWhitelabelCustomizations(window: Window): WhitelabelCustomizations | null {\n\t// @ts-ignore\n\treturn window.whitelabelCustomizations\n}\n\nexport function getThemeCustomizations(whitelabelConfig: WhitelabelConfig): ThemeCustomizations {\n\treturn JSON.parse(whitelabelConfig.jsonTheme, (k, v) => (k === \"__proto__\" ? undefined : v))\n}\n","import m from \"mithril\"\nimport { assertMainOrNodeBoot } from \"../api/common/Env\"\n\nassertMainOrNodeBoot()\n\nexport type RouteSetFn = (path: string, args: Record<string, any>) => void\n\nexport function throttleRoute(): RouteSetFn {\n\tconst limit = 200\n\tlet lastCall = 0\n\treturn function (url: string, args: Record<string, any>) {\n\t\tconst now = new Date().getTime()\n\t\ttry {\n\t\t\tm.route.set(url, args, {\n\t\t\t\treplace: now - lastCall < limit,\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tif (e.message.includes(\"can't access dead object\")) {\n\t\t\t\tconsole.log(`Caught error: ${e.message}`)\n\t\t\t} else {\n\t\t\t\tthrow e\n\t\t\t}\n\t\t}\n\n\t\tlastCall = now\n\t}\n}\n\nexport const MAIL_PREFIX = \"/mail\"\nexport const CONTACTS_PREFIX = \"/contact\"\nexport const CALENDAR_PREFIX = \"/calendar\"\nexport const SEARCH_PREFIX = \"/search\"\nexport const SETTINGS_PREFIX = \"/settings\"\nconst LogoutPath = \"/login?noAutoLogin=true\"\nexport const LogoutUrl: string = window.location.hash.startsWith(\"#mail\") ? \"/ext?noAutoLogin=true\" + location.hash : LogoutPath\n","import { deviceConfig } from \"../misc/DeviceConfig\"\nimport { assertMainOrNodeBoot, isApp, isDesktop, isTest } from \"../api/common/Env\"\nimport { downcast } from \"@tutao/tutanota-utils\"\nimport type { HtmlSanitizer } from \"../misc/HtmlSanitizer\"\nimport { NativeThemeFacade, ThemeController, WebThemeFacade } from \"./ThemeController\"\nimport { isColorLight } from \"./base/Color\"\nimport { logo_text_bright_grey, logo_text_dark_grey } from \"./builtinThemes\"\nimport { getLogoSvg } from \"./base/Logo\"\n\nassertMainOrNodeBoot()\n\n/**\n * Unique identifier for a theme.\n * There are few built-in ones and there are whitelabel ones.\n * Whitelabel themes use domain name as an ID.\n */\nexport type ThemeId = \"light\" | \"dark\" | \"blue\" | string\nexport type BaseThemeId = \"light\" | \"dark\"\nexport type Theme = {\n\tthemeId: ThemeId\n\tlogo: string\n\tbutton_bubble_bg: string\n\tbutton_bubble_fg: string\n\tcontent_bg: string\n\tcontent_fg: string\n\tcontent_button: string\n\tcontent_button_selected: string\n\tcontent_button_icon: string\n\tcontent_button_icon_selected: string\n\tcontent_button_icon_bg?: string\n\tcontent_accent: string\n\tcontent_border: string\n\tcontent_message_bg: string\n\theader_bg: string\n\theader_box_shadow_bg: string\n\theader_button: string\n\theader_button_selected: string\n\tlist_bg: string\n\tlist_alternate_bg: string\n\tlist_accent_fg: string\n\tlist_message_bg: string\n\tlist_border: string\n\tmodal_bg: string\n\televated_bg?: string\n\tnavigation_bg: string\n\tnavigation_border: string\n\tnavigation_button: string\n\tnavigation_button_icon_bg?: string\n\tnavigation_button_selected: string\n\tnavigation_button_icon: string\n\tnavigation_button_icon_selected: string\n\tnavigation_menu_bg?: string\n\tnavigation_menu_icon?: string\n}\nconst selectedThemeFacade = isApp() || isDesktop() ? new NativeThemeFacade() : new WebThemeFacade(deviceConfig)\n// We need it because we want to run tests in node and real HTMLSanitizer does not work there.\nconst sanitizerStub: Partial<HtmlSanitizer> = {\n\tsanitizeHTML: () => {\n\t\treturn {\n\t\t\thtml: \"\",\n\t\t\texternalContent: 0,\n\t\t\tinlineImageCids: [],\n\t\t\tlinks: [],\n\t\t}\n\t},\n\tsanitizeSVG(svg, configExtra?) {\n\t\tthrow new Error(\"stub!\")\n\t},\n\tsanitizeFragment(html, configExtra?) {\n\t\tthrow new Error(\"stub!\")\n\t},\n}\nexport const themeController: ThemeController = new ThemeController(\n\tselectedThemeFacade,\n\tisTest() ? () => Promise.resolve(downcast<HtmlSanitizer>(sanitizerStub)) : () => import(\"../misc/HtmlSanitizer\").then(({ htmlSanitizer }) => htmlSanitizer),\n)\n// ThemeManager.updateTheme updates the object in place, so this will always be current\n// We keep this singleton available because it is convenient to refer to, and already everywhere in the code before the addition of ThemeManager\nexport const theme = themeController._theme\n\nexport function getContentButtonIconBackground(): string {\n\treturn theme.content_button_icon_bg || theme.content_button // fallback for the new color content_button_icon_bg\n}\n\nexport function getNavButtonIconBackground(): string {\n\treturn theme.navigation_button_icon_bg || theme.navigation_button // fallback for the new color content_button_icon_bg\n}\n\nexport function getElevatedBackground(): string {\n\treturn theme.elevated_bg || theme.content_bg\n}\n\nexport function getNavigationMenuBg(): string {\n\treturn theme.navigation_menu_bg || theme.navigation_bg\n}\n\nexport function getNavigationMenuIcon(): string {\n\treturn theme.navigation_menu_icon || theme.navigation_button_icon\n}\n\nexport function getColouredTutanotaLogo(): string {\n\treturn getLogoSvg(theme.content_accent, isColorLight(theme.content_bg) ? logo_text_dark_grey : logo_text_bright_grey)\n}\n","import { animations, opacity } from \"../animation/Animations\"\nimport { client } from \"../../misc/ClientDetector\"\nimport { assertMainOrNodeBoot } from \"../../api/common/Env\"\n\nassertMainOrNodeBoot()\nconst flashedIn: Map<HTMLElement, number> = new Map() // currently flashed in element -> target opacity value\n\nconst PREVENT = (e: Event) => e.preventDefault()\n\nconst eventListenerArgs = { passive: true }\n\nexport function addFlash(target: any) {\n\tif (client.isDesktopDevice()) {\n\t\ttarget.addEventListener(\"mousedown\", flashIn, eventListenerArgs)\n\t\ttarget.addEventListener(\"mouseup\", flashOut, eventListenerArgs)\n\t\ttarget.addEventListener(\"dragstart\", PREVENT, { passive: false })\n\t\ttarget.addEventListener(\"mouseleave\", flashOut, eventListenerArgs)\n\t} else {\n\t\ttarget.addEventListener(\"touchstart\", flashIn, eventListenerArgs)\n\t\ttarget.addEventListener(\"touchend\", flashOut, eventListenerArgs)\n\t\ttarget.addEventListener(\"touchcancel\", flashOut, eventListenerArgs)\n\t}\n}\n\nexport function removeFlash(target: any) {\n\tif (client.isDesktopDevice()) {\n\t\ttarget.removeEventListener(\"mousedown\", flashIn, eventListenerArgs)\n\t\ttarget.removeEventListener(\"mouseup\", flashOut, eventListenerArgs)\n\t\ttarget.removeEventListener(\"dragstart\", PREVENT)\n\t\ttarget.removeEventListener(\"mouseleave\", flashOut, eventListenerArgs)\n\t} else {\n\t\ttarget.removeEventListener(\"touchstart\", flashIn, eventListenerArgs)\n\t\ttarget.removeEventListener(\"touchend\", flashOut, eventListenerArgs)\n\t\ttarget.removeEventListener(\"touchcancel\", flashOut, eventListenerArgs)\n\t}\n}\n\nexport function flashIn(event: MouseEvent) {\n\tlet target = event.currentTarget as any\n\tlet computedValue = getComputedOpacity(target) // use the computed value as begin value because hover only changes the computed opacity\n\n\t// keep the opacity value for the flash animation to avoid flicker on element\n\tanimations.add(target, opacity(computedValue, 0.4, true))\n\tflashedIn.set(target, computedValue)\n}\n\nexport function flashOut(event: MouseEvent) {\n\tlet target = event.currentTarget as any\n\tlet computedValue = flashedIn.get(target)\n\tif (computedValue) {\n\t\tflashOutElement(target, computedValue)\n\t}\n}\n\nexport function flashOutElement(target: HTMLElement, computedOpacity: number | null) {\n\tif (computedOpacity) {\n\t\tflashedIn.delete(target)\n\t\t// don't keep the opacity value after the animation. hover on elements won't work otherwise.\n\t\tanimations\n\t\t\t.add(target, opacity(0.4, computedOpacity, false), {\n\t\t\t\tdelay: 300,\n\t\t\t})\n\t\t\t.then(() => (target.style.opacity = \"\"))\n\t}\n}\n\nfunction getComputedOpacity(target: HTMLElement) {\n\tlet computedValue = 0\n\n\tif (window.getComputedStyle) {\n\t\tcomputedValue = Number(window.getComputedStyle(target).opacity)\n\t} else if ((target as any).currentStyle) {\n\t\tcomputedValue = Number(((target as any).currentStyle as any).opacity)\n\t}\n\n\treturn computedValue\n}\n","import { assertMainOrNodeBoot, Mode } from \"../api/common/Env\"\nimport { BrowserData, BrowserType, DeviceType } from \"./ClientConstants\"\n\nassertMainOrNodeBoot()\n\nexport class ClientDetector {\n\tuserAgent!: string\n\tbrowser!: BrowserType\n\tbrowserVersion!: number\n\tdevice!: DeviceType\n\toverflowAuto!: string\n\tisMacOS!: boolean\n\n\tconstructor() {}\n\n\tinit(userAgent: string, platform: string) {\n\t\tthis.userAgent = userAgent\n\t\tthis.browser = BrowserType.OTHER\n\t\tthis.browserVersion = 0\n\t\tthis.device = DeviceType.DESKTOP\n\n\t\tthis._setBrowserAndVersion()\n\n\t\tthis._setDeviceInfo()\n\n\t\tthis.overflowAuto = this.cssPropertyValueSupported(\"overflow\", \"overlay\") ? \"overlay\" : \"auto\"\n\t\tthis.isMacOS = platform.indexOf(\"Mac\") !== -1\n\t}\n\n\t/**\n\t * This function uses syntax constructs which we want to make sure are supported. If they are not then this file cannot be imported.\n\t */\n\tsyntaxChecks() {\n\t\t// By default rollup disables tree-shaking inside the try-catch.\n\t\ttry {\n\t\t\tconst arrowFunction = () => {\n\t\t\t\treturn 1\n\t\t\t}\n\n\t\t\tlet aLet = 2\n\n\t\t\tfunction* testGenerator() {}\n\n\t\t\tasync function testAsync() {}\n\n\t\t\tfunction testDefaultArgs(a = 2) {}\n\n\t\t\ttestGenerator()\n\t\t\ttestAsync()\n\t\t\ttestDefaultArgs()\n\t\t\tconst anArray = [1, 2, 3]\n\t\t\tconst spreadArray = [...anArray]\n\t\t\tconst dynamicString = \"\"\n\t\t\tconst impossibleCondition = arrowFunction() === aLet\n\n\t\t\tif (impossibleCondition) {\n\t\t\t\timport(dynamicString)\n\t\t\t}\n\n\t\t\tconst objectSyntax = {\n\t\t\t\t[dynamicString]: true,\n\n\t\t\t\ttestFn() {},\n\n\t\t\t\tget accessor() {\n\t\t\t\t\treturn null\n\t\t\t\t},\n\n\t\t\t\tset accessor(newValue) {},\n\t\t\t}\n\t\t\tconst templateString = `test ${dynamicString}`\n\t\t\tconst x = 1\n\t\t\tconst y = 2\n\t\t\tconst propertyShorthand = {\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t}\n\t\t\tconst { x: x2, y: y2 } = propertyShorthand\n\t\t\tconst [a1, a2, ...arest] = anArray\n\n\t\t\tclass WithStatisMember {\n\t\t\t\tstatic aFuncton() {}\n\t\t\t}\n\n\t\t\tfor (const item of testGenerator()) {\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\ttestBuiltins(): boolean {\n\t\treturn (\n\t\t\ttypeof Set !== \"undefined\" &&\n\t\t\ttypeof Map !== \"undefined\" &&\n\t\t\ttypeof Array.prototype.includes === \"function\" &&\n\t\t\ttypeof Object.entries === \"function\" &&\n\t\t\ttypeof Object.values === \"function\" &&\n\t\t\ttypeof Object.fromEntries === \"function\" &&\n\t\t\ttypeof Symbol !== \"undefined\" &&\n\t\t\ttypeof Uint8Array !== \"undefined\" &&\n\t\t\ttypeof Proxy !== \"undefined\" &&\n\t\t\ttypeof Reflect !== \"undefined\" &&\n\t\t\ttypeof Promise.prototype.finally !== \"undefined\"\n\t\t)\n\t}\n\n\ttestCss(): boolean {\n\t\ttry {\n\t\t\tdocument.querySelector(\"blockquote:not(blockquote blockquote)\")\n\t\t\tdocument.querySelectorAll(\":where(.mouse-nav)\")\n\t\t\treturn true\n\t\t} catch (e) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * Browsers which support these features are supported\n\t */\n\tisSupported(): boolean {\n\t\tthis.syntaxChecks()\n\t\treturn this.isSupportedBrowserVersion() && this.testBuiltins() && this.websockets() && this.testCss()\n\t}\n\n\tisMobileDevice(): boolean {\n\t\treturn this.device !== DeviceType.DESKTOP\n\t}\n\n\tisDesktopDevice(): boolean {\n\t\treturn this.device === DeviceType.DESKTOP\n\t}\n\n\t/**\n\t * @see https://github.com/Modernizr/Modernizr/blob/5e3f359bfc9aa511543ece60bd8a6ea8aa7defd3/feature-detects/websockets.js\n\t */\n\twebsockets(): boolean {\n\t\treturn \"WebSocket\" in window && window.WebSocket.CLOSING === 2\n\t}\n\n\tlocalStorage(): boolean {\n\t\ttry {\n\t\t\treturn localStorage != null\n\t\t} catch (e) {\n\t\t\t// DOMException is thrown if all cookies are disabled\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * @see https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js\n\t */\n\thistory(): boolean {\n\t\treturn window.history && \"pushState\" in window.history\n\t}\n\n\t/**\n\t * @see https://github.com/Modernizr/Modernizr/blob/master/feature-detects/network/xhr2.js\n\t */\n\txhr2(): boolean {\n\t\treturn \"XMLHttpRequest\" in window\n\t}\n\n\tindexedDb(): boolean {\n\t\ttry {\n\t\t\treturn window.indexedDB != null\n\t\t} catch (e) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t_setBrowserAndVersion() {\n\t\tconst operaIndex1 = this.userAgent.indexOf(\"Opera\")\n\t\tconst operaIndex2 = this.userAgent.indexOf(\"OPR/\")\n\t\tconst firefoxIndex = this.userAgent.indexOf(\"Firefox/\")\n\t\tconst paleMoonIndex = this.userAgent.indexOf(\"PaleMoon/\")\n\t\tconst iceweaselIndex = this.userAgent.indexOf(\"Iceweasel/\")\n\t\tconst chromeIndex = this.userAgent.indexOf(\"Chrome/\")\n\t\tconst chromeIosIndex = this.userAgent.indexOf(\"CriOS/\")\n\t\tconst safariIndex = this.userAgent.indexOf(\"Safari/\")\n\t\tconst edgeIndex = this.userAgent.indexOf(\"Edge\") // \"Old\" edge based on EdgeHTML, \"new\" one based on Blink has only \"Edg\"\n\n\t\tconst androidIndex = this.userAgent.indexOf(\"Android\")\n\t\tlet versionIndex = -1\n\n\t\tif (edgeIndex !== -1) {\n\t\t\tthis.browser = BrowserType.EDGE\n\t\t\tversionIndex = edgeIndex + 5\n\t\t} else if (operaIndex1 !== -1) {\n\t\t\tthis.browser = BrowserType.OPERA\n\t\t\tversionIndex = this.userAgent.indexOf(\"Version/\")\n\n\t\t\tif (versionIndex !== -1) {\n\t\t\t\tversionIndex += 8\n\t\t\t} else {\n\t\t\t\tversionIndex = operaIndex1 + 6\n\t\t\t}\n\t\t} else if (operaIndex2 !== -1) {\n\t\t\tthis.browser = BrowserType.OPERA\n\t\t\tversionIndex = operaIndex2 + 4\n\t\t} else if ((firefoxIndex !== -1 || iceweaselIndex !== -1) && operaIndex1 === -1 && operaIndex2 === -1 && paleMoonIndex === -1) {\n\t\t\t// Opera may pretend to be Firefox, so it is skipped\n\t\t\tthis.browser = BrowserType.FIREFOX\n\n\t\t\tif (firefoxIndex !== -1) {\n\t\t\t\tversionIndex = firefoxIndex + 8\n\t\t\t} else {\n\t\t\t\tversionIndex = iceweaselIndex + 10\n\t\t\t}\n\t\t} else if (chromeIndex !== -1) {\n\t\t\tthis.browser = BrowserType.CHROME\n\t\t\tversionIndex = chromeIndex + 7\n\t\t} else if (androidIndex !== -1) {\n\t\t\t// default android browser\n\t\t\t// keep this check after Chrome, Firefox and Opera, because the Android browser does not identify itself in any other way\n\t\t\tthis.browser = BrowserType.ANDROID\n\t\t\tversionIndex = androidIndex + 8\n\t\t} else if (chromeIosIndex !== -1) {\n\t\t\tthis.browser = BrowserType.CHROME\n\t\t\tversionIndex = chromeIosIndex + 6\n\t\t} else if (safariIndex !== -1 && chromeIndex === -1) {\n\t\t\t// Chrome and black berry pretends to be Safari, so it is skipped\n\t\t\tthis.browser = BrowserType.SAFARI\n\t\t\t// Safari prints its version after \"Version/\"\n\t\t\tversionIndex = this.userAgent.indexOf(\"Version/\")\n\n\t\t\tif (versionIndex !== -1) {\n\t\t\t\tversionIndex += 8\n\t\t\t} else {\n\t\t\t\t// Other browsers on iOS do not usually send Version/ and we can assume that they're Safari\n\t\t\t\tthis.extractIosVersion()\n\t\t\t\treturn\n\t\t\t}\n\t\t} else if (this.userAgent.match(/iPad.*AppleWebKit/) || this.userAgent.match(/iPhone.*AppleWebKit/)) {\n\t\t\t// iPad and iPhone do not send the Safari this.userAgent when HTML-apps are directly started from the homescreen a browser version is sent neither\n\t\t\t// after \"OS\" the iOS version is sent, so use that one\n\t\t\t// Also there are a lot of browsers on iOS but they all are based on Safari so we can use the same extraction mechanism for all of them.\n\t\t\tthis.extractIosVersion()\n\t\t\treturn\n\t\t}\n\n\t\tif (versionIndex !== -1) {\n\t\t\tconst mainVersionEndIndex = this.userAgent.indexOf(\".\", versionIndex)\n\n\t\t\tif (mainVersionEndIndex !== -1) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.browserVersion = Number(this.userAgent.substring(versionIndex, mainVersionEndIndex + 2)) // we recognize one digit after the '.'\n\t\t\t\t} catch (e) {}\n\t\t\t}\n\t\t}\n\n\t\t// if the version is not valid, the browser type is not valid, so set it to other\n\t\tif (this.browserVersion === 0) {\n\t\t\tthis.browser = BrowserType.OTHER\n\t\t}\n\t}\n\n\textractIosVersion() {\n\t\t// Extracting version does not work with iPad OS WebView because it's not in the userAgent. We could look it up\n\t\t// from Webkit version but maybe we don't need that for now.\n\t\tconst versionIndex = this.userAgent.indexOf(\" OS \")\n\n\t\tif (versionIndex !== -1) {\n\t\t\tthis.browser = BrowserType.SAFARI\n\n\t\t\ttry {\n\t\t\t\t// in case of versions like 12_1_1 get substring 12_1 and convert it to 12.1\n\t\t\t\tlet pos = versionIndex + 4\n\t\t\t\tlet hadNan = false\n\n\t\t\t\twhile (pos < this.userAgent.length) {\n\t\t\t\t\tpos++\n\n\t\t\t\t\tif (isNaN(Number(this.userAgent.charAt(pos)))) {\n\t\t\t\t\t\tif (hadNan) {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\thadNan = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst numberString = this.userAgent.substring(versionIndex + 4, pos)\n\t\t\t\tthis.browserVersion = Number(numberString.replace(/_/g, \".\"))\n\t\t\t} catch (e) {}\n\t\t}\n\t}\n\n\t_setDeviceInfo() {\n\t\tthis.device = DeviceType.DESKTOP\n\n\t\tif (\n\t\t\tthis.userAgent.match(/iPad.*AppleWebKit/) != null || // iPadOS does not differ in UserAgent from Safari on macOS. Use hack with TouchEvent to detect iPad\n\t\t\t// Desktop Chrome has TouchEvent but it also has Chrome in it. Mobile iOS has CriOS in it and not Chrome.\n\t\t\t(/Macintosh; Intel Mac OS X.*AppleWebKit/.test(this.userAgent) && window.TouchEvent && /.*Chrome.*/.test(this.userAgent) === false)\n\t\t) {\n\t\t\tthis.device = DeviceType.IPAD\n\t\t} else if (this.userAgent.match(/iPhone.*AppleWebKit/) != null) {\n\t\t\tthis.device = DeviceType.IPHONE\n\t\t} else if (this.userAgent.match(/Android/) != null) {\n\t\t\tif (this.userAgent.match(/Ubuntu/) != null) {\n\t\t\t\tthis.device = DeviceType.OTHER_MOBILE\n\t\t\t} else {\n\t\t\t\tthis.device = DeviceType.ANDROID\n\t\t\t}\n\t\t} else if (this.userAgent.match(/Windows NT/) != null) {\n\t\t\tthis.device = DeviceType.DESKTOP\n\t\t} else if (this.userAgent.match(/Mobile/) != null || this.userAgent.match(/Tablet/) != null) {\n\t\t\tthis.device = DeviceType.OTHER_MOBILE\n\t\t}\n\t}\n\n\tisTouchSupported(): boolean {\n\t\treturn \"ontouchstart\" in window\n\t}\n\n\tisIos(): boolean {\n\t\treturn this.device === DeviceType.IPAD || this.device === DeviceType.IPHONE\n\t}\n\n\tcssPropertyValueSupported(prop: string, value: string): boolean {\n\t\tlet d = document.createElement(\"div\") as any\n\t\td.style[prop] = value\n\t\treturn d.style[prop] === value\n\t}\n\n\tgetIdentifier(): string {\n\t\tif (env.mode === Mode.App) {\n\t\t\treturn client.device + \" App\"\n\t\t} else if (env.mode === Mode.Browser) {\n\t\t\treturn client.browser + \" Browser\"\n\t\t} else if (env.platformId === \"linux\") {\n\t\t\treturn \"Linux Desktop\"\n\t\t} else if (env.platformId === \"darwin\") {\n\t\t\treturn \"Mac Desktop\"\n\t\t} else if (env.platformId === \"win32\") {\n\t\t\treturn \"Windows Desktop\"\n\t\t}\n\n\t\treturn \"Unknown\"\n\t}\n\n\tisSupportedBrowserVersion(): boolean {\n\t\treturn this.notOldFirefox() && this.notOldChrome()\n\t}\n\n\tnotOldFirefox(): boolean {\n\t\t// issue only occurs for old Firefox browsers\n\t\t// https://github.com/tutao/tutanota/issues/835\n\t\treturn this.browser !== BrowserType.FIREFOX || this.browserVersion > 40\n\t}\n\n\tnotOldChrome(): boolean {\n\t\treturn this.browser !== BrowserType.CHROME || this.browserVersion > 55\n\t}\n\n\tneedsMicrotaskHack(): boolean {\n\t\treturn (\n\t\t\tthis.isIos() ||\n\t\t\tthis.browser === BrowserType.SAFARI ||\n\t\t\t(this.browser === BrowserType.FIREFOX && this.browserVersion <= 60) ||\n\t\t\t(this.browser === BrowserType.CHROME && this.browserVersion < 59)\n\t\t)\n\t}\n\n\tneedsExplicitIDBIds(): boolean {\n\t\treturn this.browser === BrowserType.SAFARI && this.browserVersion < 12.2\n\t}\n\n\tbrowserData(): BrowserData {\n\t\treturn {\n\t\t\tneedsMicrotaskHack: this.needsMicrotaskHack(),\n\t\t\tneedsExplicitIDBIds: this.needsExplicitIDBIds(),\n\t\t\tindexedDbSupported: this.indexedDb(),\n\t\t}\n\t}\n}\n\nexport const client: ClientDetector = new ClientDetector()\n","/// ivk: patched to fix early console binding\n/// ivk: patched to remove promise polyfill and m.request\n;(function() {\n\"use strict\"\nfunction Vnode(tag, key, attrs0, children, text, dom) {\n\treturn {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: undefined, events: undefined, instance: undefined}\n}\nVnode.normalize = function(node) {\n\tif (Array.isArray(node)) return Vnode(\"[\", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined)\n\tif (node == null || typeof node === \"boolean\") return null\n\tif (typeof node === \"object\") return node\n\treturn Vnode(\"#\", undefined, undefined, String(node), undefined, undefined)\n}\nVnode.normalizeChildren = function(input) {\n\tvar children = []\n\tif (input.length) {\n\t\tvar isKeyed = input[0] != null && input[0].key != null\n\t\t// Note: this is a *very* perf-sensitive check.\n\t\t// Fun fact: merging the loop like this is somehow faster than splitting\n\t\t// it, noticeably so.\n\t\tfor (var i = 1; i < input.length; i++) {\n\t\t\tif ((input[i] != null && input[i].key != null) !== isKeyed) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\tisKeyed && (input[i] != null || typeof input[i] === \"boolean\")\n\t\t\t\t\t\t? \"In fragments, vnodes must either all have keys or none have keys. You may wish to consider using an explicit keyed empty fragment, m.fragment({key: ...}), instead of a hole.\"\n\t\t\t\t\t\t: \"In fragments, vnodes must either all have keys or none have keys.\"\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tfor (var i = 0; i < input.length; i++) {\n\t\t\tchildren[i] = Vnode.normalize(input[i])\n\t\t}\n\t}\n\treturn children\n}\n// Call via `hyperscriptVnode0.apply(startOffset, arguments)`\n//\n// The reason I do it this way, forwarding the arguments and passing the start\n// offset in `this`, is so I don't have to create a temporary array in a\n// performance-critical path.\n//\n// In native ES6, I'd instead add a final `...args` parameter to the\n// `hyperscript0` and `fragment` factories and define this as\n// `hyperscriptVnode0(...args)`, since modern engines do optimize that away. But\n// ES5 (what Mithril.js requires thanks to IE support) doesn't give me that luxury,\n// and engines aren't nearly intelligent enough to do either of these:\n//\n// 1. Elide the allocation for `[].slice.call(arguments, 1)` when it's passed to\n//    another function only to be indexed.\n// 2. Elide an `arguments` allocation when it's passed to any function other\n//    than `Function.prototype.apply` or `Reflect.apply`.\n//\n// In ES6, it'd probably look closer to this (I'd need to profile it, though):\n// var hyperscriptVnode = function(attrs1, ...children0) {\n//     if (attrs1 == null || typeof attrs1 === \"object\" && attrs1.tag == null && !Array.isArray(attrs1)) {\n//         if (children0.length === 1 && Array.isArray(children0[0])) children0 = children0[0]\n//     } else {\n//         children0 = children0.length === 0 && Array.isArray(attrs1) ? attrs1 : [attrs1, ...children0]\n//         attrs1 = undefined\n//     }\n//\n//     if (attrs1 == null) attrs1 = {}\n//     return Vnode(\"\", attrs1.key, attrs1, children0)\n// }\nvar hyperscriptVnode = function() {\n\tvar attrs1 = arguments[this], start = this + 1, children0\n\tif (attrs1 == null) {\n\t\tattrs1 = {}\n\t} else if (typeof attrs1 !== \"object\" || attrs1.tag != null || Array.isArray(attrs1)) {\n\t\tattrs1 = {}\n\t\tstart = this\n\t}\n\tif (arguments.length === start + 1) {\n\t\tchildren0 = arguments[start]\n\t\tif (!Array.isArray(children0)) children0 = [children0]\n\t} else {\n\t\tchildren0 = []\n\t\twhile (start < arguments.length) children0.push(arguments[start++])\n\t}\n\treturn Vnode(\"\", attrs1.key, attrs1, children0)\n}\n// This exists so I'm1 only saving it once.\nvar hasOwn = {}.hasOwnProperty\nvar selectorParser = /(?:(^|#|\\.)([^#\\.\\[\\]]+))|(\\[(.+?)(?:\\s*=\\s*(\"|'|)((?:\\\\[\"'\\]]|.)*?)\\5)?\\])/g\nvar selectorCache = {}\nfunction isEmpty(object) {\n\tfor (var key in object) if (hasOwn.call(object, key)) return false\n\treturn true\n}\nfunction compileSelector(selector) {\n\tvar match, tag = \"div\", classes = [], attrs = {}\n\twhile (match = selectorParser.exec(selector)) {\n\t\tvar type = match[1], value = match[2]\n\t\tif (type === \"\" && value !== \"\") tag = value\n\t\telse if (type === \"#\") attrs.id = value\n\t\telse if (type === \".\") classes.push(value)\n\t\telse if (match[3][0] === \"[\") {\n\t\t\tvar attrValue = match[6]\n\t\t\tif (attrValue) attrValue = attrValue.replace(/\\\\([\"'])/g, \"$1\").replace(/\\\\\\\\/g, \"\\\\\")\n\t\t\tif (match[4] === \"class\") classes.push(attrValue)\n\t\t\telse attrs[match[4]] = attrValue === \"\" ? attrValue : attrValue || true\n\t\t}\n\t}\n\tif (classes.length > 0) attrs.className = classes.join(\" \")\n\treturn selectorCache[selector] = {tag: tag, attrs: attrs}\n}\nfunction execSelector(state, vnode) {\n\tvar attrs = vnode.attrs\n\tvar hasClass = hasOwn.call(attrs, \"class\")\n\tvar className = hasClass ? attrs.class : attrs.className\n\tvnode.tag = state.tag\n\tvnode.attrs = {}\n\tif (!isEmpty(state.attrs) && !isEmpty(attrs)) {\n\t\tvar newAttrs = {}\n\t\tfor (var key in attrs) {\n\t\t\tif (hasOwn.call(attrs, key)) newAttrs[key] = attrs[key]\n\t\t}\n\t\tattrs = newAttrs\n\t}\n\tfor (var key in state.attrs) {\n\t\tif (hasOwn.call(state.attrs, key) && key !== \"className\" && !hasOwn.call(attrs, key)){\n\t\t\tattrs[key] = state.attrs[key]\n\t\t}\n\t}\n\tif (className != null || state.attrs.className != null) attrs.className =\n\t\tclassName != null\n\t\t\t? state.attrs.className != null\n\t\t\t\t? String(state.attrs.className) + \" \" + String(className)\n\t\t\t\t: className\n\t\t\t: state.attrs.className != null\n\t\t\t\t? state.attrs.className\n\t\t\t\t: null\n\tif (hasClass) attrs.class = null\n\tfor (var key in attrs) {\n\t\tif (hasOwn.call(attrs, key) && key !== \"key\") {\n\t\t\tvnode.attrs = attrs\n\t\t\tbreak\n\t\t}\n\t}\n\treturn vnode\n}\nfunction hyperscript(selector) {\n\tif (selector == null || typeof selector !== \"string\" && typeof selector !== \"function\" && typeof selector.view !== \"function\") {\n\t\tthrow Error(\"The selector must be either a string or a component.\");\n\t}\n\tvar vnode = hyperscriptVnode.apply(1, arguments)\n\tif (typeof selector === \"string\") {\n\t\tvnode.children = Vnode.normalizeChildren(vnode.children)\n\t\tif (selector !== \"[\") return execSelector(selectorCache[selector] || compileSelector(selector), vnode)\n\t}\n\tvnode.tag = selector\n\treturn vnode\n}\nhyperscript.trust = function(html) {\n\tif (html == null) html = \"\"\n\treturn Vnode(\"<\", undefined, undefined, html, undefined, undefined)\n}\nhyperscript.fragment = function() {\n\tvar vnode2 = hyperscriptVnode.apply(0, arguments)\n\tvnode2.tag = \"[\"\n\tvnode2.children = Vnode.normalizeChildren(vnode2.children)\n\treturn vnode2\n}\n/* global window */\nvar _13 = function($window) {\n\tvar $doc = $window && $window.document\n\tvar currentRedraw\n\tvar nameSpace = {\n\t\tsvg: \"http://www.w3.org/2000/svg\",\n\t\tmath: \"http://www.w3.org/1998/Math/MathML\"\n\t}\n\tfunction getNameSpace(vnode3) {\n\t\treturn vnode3.attrs && vnode3.attrs.xmlns || nameSpace[vnode3.tag]\n\t}\n\t//sanity check to discourage people from doing `vnode3.state = ...`\n\tfunction checkState(vnode3, original) {\n\t\tif (vnode3.state !== original) throw new Error(\"'vnode.state' must not be modified.\")\n\t}\n\t//Note: the hook is passed as the `this` argument to allow proxying the\n\t//arguments without requiring a full array allocation to do so. It also\n\t//takes advantage of the fact the current `vnode3` is the first argument in\n\t//all lifecycle methods.\n\tfunction callHook(vnode3) {\n\t\tvar original = vnode3.state\n\t\ttry {\n\t\t\treturn this.apply(original, arguments)\n\t\t} finally {\n\t\t\tcheckState(vnode3, original)\n\t\t}\n\t}\n\t// IE11 (at least) throws an UnspecifiedError when accessing document.activeElement when\n\t// inside an iframe. Catch and swallow this error, and heavy-handidly return null.\n\tfunction activeElement() {\n\t\ttry {\n\t\t\treturn $doc.activeElement\n\t\t} catch (e) {\n\t\t\treturn null\n\t\t}\n\t}\n\t//create\n\tfunction createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) {\n\t\tfor (var i = start; i < end; i++) {\n\t\t\tvar vnode3 = vnodes[i]\n\t\t\tif (vnode3 != null) {\n\t\t\t\tcreateNode(parent, vnode3, hooks, ns, nextSibling)\n\t\t\t}\n\t\t}\n\t}\n\tfunction createNode(parent, vnode3, hooks, ns, nextSibling) {\n\t\tvar tag = vnode3.tag\n\t\tif (typeof tag === \"string\") {\n\t\t\tvnode3.state = {}\n\t\t\tif (vnode3.attrs != null) initLifecycle(vnode3.attrs, vnode3, hooks)\n\t\t\tswitch (tag) {\n\t\t\t\tcase \"#\": createText(parent, vnode3, nextSibling); break\n\t\t\t\tcase \"<\": createHTML(parent, vnode3, ns, nextSibling); break\n\t\t\t\tcase \"[\": createFragment(parent, vnode3, hooks, ns, nextSibling); break\n\t\t\t\tdefault: createElement(parent, vnode3, hooks, ns, nextSibling)\n\t\t\t}\n\t\t}\n\t\telse createComponent(parent, vnode3, hooks, ns, nextSibling)\n\t}\n\tfunction createText(parent, vnode3, nextSibling) {\n\t\tvnode3.dom = $doc.createTextNode(vnode3.children)\n\t\tinsertNode(parent, vnode3.dom, nextSibling)\n\t}\n\tvar possibleParents = {caption: \"table\", thead: \"table\", tbody: \"table\", tfoot: \"table\", tr: \"tbody\", th: \"tr\", td: \"tr\", colgroup: \"table\", col: \"colgroup\"}\n\tfunction createHTML(parent, vnode3, ns, nextSibling) {\n\t\tvar match0 = vnode3.children.match(/^\\s*?<(\\w+)/im) || []\n\t\t// not using the proper parent makes the child element(s) vanish.\n\t\t//     var div = document.createElement(\"div\")\n\t\t//     div.innerHTML = \"<td>i</td><td>j</td>\"\n\t\t//     console.log(div.innerHTML)\n\t\t// --> \"ij\", no <td> in sight.\n\t\tvar temp = $doc.createElement(possibleParents[match0[1]] || \"div\")\n\t\tif (ns === \"http://www.w3.org/2000/svg\") {\n\t\t\ttemp.innerHTML = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\">\" + vnode3.children + \"</svg>\"\n\t\t\ttemp = temp.firstChild\n\t\t} else {\n\t\t\ttemp.innerHTML = vnode3.children\n\t\t}\n\t\tvnode3.dom = temp.firstChild\n\t\tvnode3.domSize = temp.childNodes.length\n\t\t// Capture nodes to remove, so we don't confuse them.\n\t\tvnode3.instance = []\n\t\tvar fragment = $doc.createDocumentFragment()\n\t\tvar child\n\t\twhile (child = temp.firstChild) {\n\t\t\tvnode3.instance.push(child)\n\t\t\tfragment.appendChild(child)\n\t\t}\n\t\tinsertNode(parent, fragment, nextSibling)\n\t}\n\tfunction createFragment(parent, vnode3, hooks, ns, nextSibling) {\n\t\tvar fragment = $doc.createDocumentFragment()\n\t\tif (vnode3.children != null) {\n\t\t\tvar children2 = vnode3.children\n\t\t\tcreateNodes(fragment, children2, 0, children2.length, hooks, null, ns)\n\t\t}\n\t\tvnode3.dom = fragment.firstChild\n\t\tvnode3.domSize = fragment.childNodes.length\n\t\tinsertNode(parent, fragment, nextSibling)\n\t}\n\tfunction createElement(parent, vnode3, hooks, ns, nextSibling) {\n\t\tvar tag = vnode3.tag\n\t\tvar attrs2 = vnode3.attrs\n\t\tvar is = attrs2 && attrs2.is\n\t\tns = getNameSpace(vnode3) || ns\n\t\tvar element = ns ?\n\t\t\tis ? $doc.createElementNS(ns, tag, {is: is}) : $doc.createElementNS(ns, tag) :\n\t\t\tis ? $doc.createElement(tag, {is: is}) : $doc.createElement(tag)\n\t\tvnode3.dom = element\n\t\tif (attrs2 != null) {\n\t\t\tsetAttrs(vnode3, attrs2, ns)\n\t\t}\n\t\tinsertNode(parent, element, nextSibling)\n\t\tif (!maybeSetContentEditable(vnode3)) {\n\t\t\tif (vnode3.children != null) {\n\t\t\t\tvar children2 = vnode3.children\n\t\t\t\tcreateNodes(element, children2, 0, children2.length, hooks, null, ns)\n\t\t\t\tif (vnode3.tag === \"select\" && attrs2 != null) setLateSelectAttrs(vnode3, attrs2)\n\t\t\t}\n\t\t}\n\t}\n\tfunction initComponent(vnode3, hooks) {\n\t\tvar sentinel\n\t\tif (typeof vnode3.tag.view === \"function\") {\n\t\t\tvnode3.state = Object.create(vnode3.tag)\n\t\t\tsentinel = vnode3.state.view\n\t\t\tif (sentinel.$$reentrantLock$$ != null) return\n\t\t\tsentinel.$$reentrantLock$$ = true\n\t\t} else {\n\t\t\tvnode3.state = void 0\n\t\t\tsentinel = vnode3.tag\n\t\t\tif (sentinel.$$reentrantLock$$ != null) return\n\t\t\tsentinel.$$reentrantLock$$ = true\n\t\t\tvnode3.state = (vnode3.tag.prototype != null && typeof vnode3.tag.prototype.view === \"function\") ? new vnode3.tag(vnode3) : vnode3.tag(vnode3)\n\t\t}\n\t\tinitLifecycle(vnode3.state, vnode3, hooks)\n\t\tif (vnode3.attrs != null) initLifecycle(vnode3.attrs, vnode3, hooks)\n\t\tvnode3.instance = Vnode.normalize(callHook.call(vnode3.state.view, vnode3))\n\t\tif (vnode3.instance === vnode3) throw Error(\"A view cannot return the vnode it received as argument\")\n\t\tsentinel.$$reentrantLock$$ = null\n\t}\n\tfunction createComponent(parent, vnode3, hooks, ns, nextSibling) {\n\t\tinitComponent(vnode3, hooks)\n\t\tif (vnode3.instance != null) {\n\t\t\tcreateNode(parent, vnode3.instance, hooks, ns, nextSibling)\n\t\t\tvnode3.dom = vnode3.instance.dom\n\t\t\tvnode3.domSize = vnode3.dom != null ? vnode3.instance.domSize : 0\n\t\t}\n\t\telse {\n\t\t\tvnode3.domSize = 0\n\t\t}\n\t}\n\t//update\n\t/**\n\t * @param {Element|Fragment} parent - the parent element\n\t * @param {Vnode[] | null} old - the list of vnodes of the last `render0()` call for\n\t *                               this part of the tree\n\t * @param {Vnode[] | null} vnodes - as above, but for the current `render0()` call.\n\t * @param {Function[]} hooks - an accumulator of post-render0 hooks (oncreate/onupdate)\n\t * @param {Element | null} nextSibling - the next DOM node if we're dealing with a\n\t *                                       fragment that is not the last item in its\n\t *                                       parent\n\t * @param {'svg' | 'math' | String | null} ns) - the current XML namespace, if any\n\t * @returns void\n\t */\n\t// This function diffs and patches lists of vnodes, both keyed and unkeyed.\n\t//\n\t// We will:\n\t//\n\t// 1. describe its general structure\n\t// 2. focus on the diff algorithm optimizations\n\t// 3. discuss DOM node operations.\n\t// ## Overview:\n\t//\n\t// The updateNodes() function:\n\t// - deals with trivial cases\n\t// - determines whether the lists are keyed or unkeyed based on the first non-null node\n\t//   of each list.\n\t// - diffs them and patches the DOM if needed (that's the brunt of the code)\n\t// - manages the leftovers: after diffing, are there:\n\t//   - old nodes left to remove?\n\t// \t - new nodes to insert?\n\t// \t deal with them!\n\t//\n\t// The lists are only iterated over once, with an exception for the nodes in `old` that\n\t// are visited in the fourth part of the diff and in the `removeNodes` loop.\n\t// ## Diffing\n\t//\n\t// Reading https://github.com/localvoid/ivi/blob/ddc09d06abaef45248e6133f7040d00d3c6be853/packages/ivi/src/vdom/implementation.ts#L617-L837\n\t// may be good for context on longest increasing subsequence-based logic for moving nodes.\n\t//\n\t// In order to diff keyed lists, one has to\n\t//\n\t// 1) match0 nodes in both lists, per key, and update them accordingly\n\t// 2) create the nodes present in the new list, but absent in the old one\n\t// 3) remove the nodes present in the old list, but absent in the new one\n\t// 4) figure out what nodes in 1) to move in order to minimize the DOM operations.\n\t//\n\t// To achieve 1) one can create a dictionary of keys => index (for the old list), then0 iterate\n\t// over the new list and for each new vnode3, find the corresponding vnode3 in the old list using\n\t// the map.\n\t// 2) is achieved in the same step: if a new node has no corresponding entry in the map, it is new\n\t// and must be created.\n\t// For the removals, we actually remove the nodes that have been updated from the old list.\n\t// The nodes that remain in that list after 1) and 2) have been performed can be safely removed.\n\t// The fourth step is a bit more complex and relies on the longest increasing subsequence (LIS)\n\t// algorithm.\n\t//\n\t// the longest increasing subsequence is the list of nodes that can remain in place. Imagine going\n\t// from `1,2,3,4,5` to `4,5,1,2,3` where the numbers are not necessarily the keys, but the indices\n\t// corresponding to the keyed nodes in the old list (keyed nodes `e,d,c,b,a` => `b,a,e,d,c` would\n\t//  match0 the above lists, for example).\n\t//\n\t// In there are two increasing subsequences: `4,5` and `1,2,3`, the latter being the longest. We\n\t// can update those nodes without moving them, and only call `insertNode` on `4` and `5`.\n\t//\n\t// @localvoid adapted the algo to also support node deletions and insertions (the `lis` is actually\n\t// the longest increasing subsequence *of old nodes still present in the new list*).\n\t//\n\t// It is a general algorithm that is fireproof in all circumstances, but it requires the allocation\n\t// and the construction of a `key => oldIndex` map, and three arrays (one with `newIndex => oldIndex`,\n\t// the `LIS` and a temporary one to create the LIS).\n\t//\n\t// So we cheat where we can: if the tails of the lists are identical, they are guaranteed to be part of\n\t// the LIS and can be updated without moving them.\n\t//\n\t// If two nodes are swapped, they are guaranteed not to be part of the LIS, and must be moved (with\n\t// the exception of the last node if the list is fully reversed).\n\t//\n\t// ## Finding the next sibling.\n\t//\n\t// `updateNode()` and `createNode()` expect a nextSibling parameter to perform DOM operations.\n\t// When the list is being traversed top-down, at any index, the DOM nodes up to the previous\n\t// vnode3 reflect the content of the new list, whereas the rest of the DOM nodes reflect the old\n\t// list. The next sibling must be looked for in the old list using `getNextSibling(... oldStart + 1 ...)`.\n\t//\n\t// In the other scenarios (swaps, upwards traversal, map-based diff),\n\t// the new vnodes list is traversed upwards. The DOM nodes at the bottom of the list reflect the\n\t// bottom part of the new vnodes list, and we can use the `v.dom`  value of the previous node\n\t// as the next sibling (cached in the `nextSibling` variable).\n\t// ## DOM node moves\n\t//\n\t// In most scenarios `updateNode()` and `createNode()` perform the DOM operations. However,\n\t// this is not the case if the node moved (second and fourth part of the diff algo). We move\n\t// the old DOM nodes before updateNode runs0 because it enables us to use the cached `nextSibling`\n\t// variable rather than fetching it using `getNextSibling()`.\n\t//\n\t// The fourth part of the diff currently inserts nodes unconditionally, leading to issues\n\t// like #1791 and #1999. We need to be smarter about those situations where adjascent old\n\t// nodes remain together in the new list in a way that isn't covered by parts one and\n\t// three of the diff algo.\n\tfunction updateNodes(parent, old, vnodes, hooks, nextSibling, ns) {\n\t\tif (old === vnodes || old == null && vnodes == null) return\n\t\telse if (old == null || old.length === 0) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, ns)\n\t\telse if (vnodes == null || vnodes.length === 0) removeNodes(parent, old, 0, old.length)\n\t\telse {\n\t\t\tvar isOldKeyed = old[0] != null && old[0].key != null\n\t\t\tvar isKeyed0 = vnodes[0] != null && vnodes[0].key != null\n\t\t\tvar start = 0, oldStart = 0\n\t\t\tif (!isOldKeyed) while (oldStart < old.length && old[oldStart] == null) oldStart++\n\t\t\tif (!isKeyed0) while (start < vnodes.length && vnodes[start] == null) start++\n\t\t\tif (isOldKeyed !== isKeyed0) {\n\t\t\t\tremoveNodes(parent, old, oldStart, old.length)\n\t\t\t\tcreateNodes(parent, vnodes, start, vnodes.length, hooks, nextSibling, ns)\n\t\t\t} else if (!isKeyed0) {\n\t\t\t\t// Don't index past the end of either list (causes deopts).\n\t\t\t\tvar commonLength = old.length < vnodes.length ? old.length : vnodes.length\n\t\t\t\t// Rewind if necessary to the first non-null index on either side.\n\t\t\t\t// We could alternatively either explicitly create or remove nodes when `start !== oldStart`\n\t\t\t\t// but that would be optimizing for sparse lists which are more rare than dense ones.\n\t\t\t\tstart = start < oldStart ? start : oldStart\n\t\t\t\tfor (; start < commonLength; start++) {\n\t\t\t\t\to = old[start]\n\t\t\t\t\tv = vnodes[start]\n\t\t\t\t\tif (o === v || o == null && v == null) continue\n\t\t\t\t\telse if (o == null) createNode(parent, v, hooks, ns, getNextSibling(old, start + 1, nextSibling))\n\t\t\t\t\telse if (v == null) removeNode(parent, o)\n\t\t\t\t\telse updateNode(parent, o, v, hooks, getNextSibling(old, start + 1, nextSibling), ns)\n\t\t\t\t}\n\t\t\t\tif (old.length > commonLength) removeNodes(parent, old, start, old.length)\n\t\t\t\tif (vnodes.length > commonLength) createNodes(parent, vnodes, start, vnodes.length, hooks, nextSibling, ns)\n\t\t\t} else {\n\t\t\t\t// keyed diff\n\t\t\t\tvar oldEnd = old.length - 1, end = vnodes.length - 1, map, o, v, oe, ve, topSibling\n\t\t\t\t// bottom-up\n\t\t\t\twhile (oldEnd >= oldStart && end >= start) {\n\t\t\t\t\toe = old[oldEnd]\n\t\t\t\t\tve = vnodes[end]\n\t\t\t\t\tif (oe.key !== ve.key) break\n\t\t\t\t\tif (oe !== ve) updateNode(parent, oe, ve, hooks, nextSibling, ns)\n\t\t\t\t\tif (ve.dom != null) nextSibling = ve.dom\n\t\t\t\t\toldEnd--, end--\n\t\t\t\t}\n\t\t\t\t// top-down\n\t\t\t\twhile (oldEnd >= oldStart && end >= start) {\n\t\t\t\t\to = old[oldStart]\n\t\t\t\t\tv = vnodes[start]\n\t\t\t\t\tif (o.key !== v.key) break\n\t\t\t\t\toldStart++, start++\n\t\t\t\t\tif (o !== v) updateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), ns)\n\t\t\t\t}\n\t\t\t\t// swaps and list reversals\n\t\t\t\twhile (oldEnd >= oldStart && end >= start) {\n\t\t\t\t\tif (start === end) break\n\t\t\t\t\tif (o.key !== ve.key || oe.key !== v.key) break\n\t\t\t\t\ttopSibling = getNextSibling(old, oldStart, nextSibling)\n\t\t\t\t\tmoveNodes(parent, oe, topSibling)\n\t\t\t\t\tif (oe !== v) updateNode(parent, oe, v, hooks, topSibling, ns)\n\t\t\t\t\tif (++start <= --end) moveNodes(parent, o, nextSibling)\n\t\t\t\t\tif (o !== ve) updateNode(parent, o, ve, hooks, nextSibling, ns)\n\t\t\t\t\tif (ve.dom != null) nextSibling = ve.dom\n\t\t\t\t\toldStart++; oldEnd--\n\t\t\t\t\toe = old[oldEnd]\n\t\t\t\t\tve = vnodes[end]\n\t\t\t\t\to = old[oldStart]\n\t\t\t\t\tv = vnodes[start]\n\t\t\t\t}\n\t\t\t\t// bottom up once again\n\t\t\t\twhile (oldEnd >= oldStart && end >= start) {\n\t\t\t\t\tif (oe.key !== ve.key) break\n\t\t\t\t\tif (oe !== ve) updateNode(parent, oe, ve, hooks, nextSibling, ns)\n\t\t\t\t\tif (ve.dom != null) nextSibling = ve.dom\n\t\t\t\t\toldEnd--, end--\n\t\t\t\t\toe = old[oldEnd]\n\t\t\t\t\tve = vnodes[end]\n\t\t\t\t}\n\t\t\t\tif (start > end) removeNodes(parent, old, oldStart, oldEnd + 1)\n\t\t\t\telse if (oldStart > oldEnd) createNodes(parent, vnodes, start, end + 1, hooks, nextSibling, ns)\n\t\t\t\telse {\n\t\t\t\t\t// inspired by ivi https://github.com/ivijs/ivi/ by Boris Kaul\n\t\t\t\t\tvar originalNextSibling = nextSibling, vnodesLength = end - start + 1, oldIndices = new Array(vnodesLength), li=0, i=0, pos = 2147483647, matched = 0, map, lisIndices\n\t\t\t\t\tfor (i = 0; i < vnodesLength; i++) oldIndices[i] = -1\n\t\t\t\t\tfor (i = end; i >= start; i--) {\n\t\t\t\t\t\tif (map == null) map = getKeyMap(old, oldStart, oldEnd + 1)\n\t\t\t\t\t\tve = vnodes[i]\n\t\t\t\t\t\tvar oldIndex = map[ve.key]\n\t\t\t\t\t\tif (oldIndex != null) {\n\t\t\t\t\t\t\tpos = (oldIndex < pos) ? oldIndex : -1 // becomes -1 if nodes were re-ordered\n\t\t\t\t\t\t\toldIndices[i-start] = oldIndex\n\t\t\t\t\t\t\toe = old[oldIndex]\n\t\t\t\t\t\t\told[oldIndex] = null\n\t\t\t\t\t\t\tif (oe !== ve) updateNode(parent, oe, ve, hooks, nextSibling, ns)\n\t\t\t\t\t\t\tif (ve.dom != null) nextSibling = ve.dom\n\t\t\t\t\t\t\tmatched++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tnextSibling = originalNextSibling\n\t\t\t\t\tif (matched !== oldEnd - oldStart + 1) removeNodes(parent, old, oldStart, oldEnd + 1)\n\t\t\t\t\tif (matched === 0) createNodes(parent, vnodes, start, end + 1, hooks, nextSibling, ns)\n\t\t\t\t\telse {\n\t\t\t\t\t\tif (pos === -1) {\n\t\t\t\t\t\t\t// the indices of the indices of the items that are part of the\n\t\t\t\t\t\t\t// longest increasing subsequence in the oldIndices list\n\t\t\t\t\t\t\tlisIndices = makeLisIndices(oldIndices)\n\t\t\t\t\t\t\tli = lisIndices.length - 1\n\t\t\t\t\t\t\tfor (i = end; i >= start; i--) {\n\t\t\t\t\t\t\t\tv = vnodes[i]\n\t\t\t\t\t\t\t\tif (oldIndices[i-start] === -1) createNode(parent, v, hooks, ns, nextSibling)\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tif (lisIndices[li] === i - start) li--\n\t\t\t\t\t\t\t\t\telse moveNodes(parent, v, nextSibling)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (v.dom != null) nextSibling = vnodes[i].dom\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfor (i = end; i >= start; i--) {\n\t\t\t\t\t\t\t\tv = vnodes[i]\n\t\t\t\t\t\t\t\tif (oldIndices[i-start] === -1) createNode(parent, v, hooks, ns, nextSibling)\n\t\t\t\t\t\t\t\tif (v.dom != null) nextSibling = vnodes[i].dom\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfunction updateNode(parent, old, vnode3, hooks, nextSibling, ns) {\n\t\tvar oldTag = old.tag, tag = vnode3.tag\n\t\tif (oldTag === tag) {\n\t\t\tvnode3.state = old.state\n\t\t\tvnode3.events = old.events\n\t\t\tif (shouldNotUpdate(vnode3, old)) return\n\t\t\tif (typeof oldTag === \"string\") {\n\t\t\t\tif (vnode3.attrs != null) {\n\t\t\t\t\tupdateLifecycle(vnode3.attrs, vnode3, hooks)\n\t\t\t\t}\n\t\t\t\tswitch (oldTag) {\n\t\t\t\t\tcase \"#\": updateText(old, vnode3); break\n\t\t\t\t\tcase \"<\": updateHTML(parent, old, vnode3, ns, nextSibling); break\n\t\t\t\t\tcase \"[\": updateFragment(parent, old, vnode3, hooks, nextSibling, ns); break\n\t\t\t\t\tdefault: updateElement(old, vnode3, hooks, ns)\n\t\t\t\t}\n\t\t\t}\n\t\t\telse updateComponent(parent, old, vnode3, hooks, nextSibling, ns)\n\t\t}\n\t\telse {\n\t\t\tremoveNode(parent, old)\n\t\t\tcreateNode(parent, vnode3, hooks, ns, nextSibling)\n\t\t}\n\t}\n\tfunction updateText(old, vnode3) {\n\t\tif (old.children.toString() !== vnode3.children.toString()) {\n\t\t\told.dom.nodeValue = vnode3.children\n\t\t}\n\t\tvnode3.dom = old.dom\n\t}\n\tfunction updateHTML(parent, old, vnode3, ns, nextSibling) {\n\t\tif (old.children !== vnode3.children) {\n\t\t\tremoveHTML(parent, old)\n\t\t\tcreateHTML(parent, vnode3, ns, nextSibling)\n\t\t}\n\t\telse {\n\t\t\tvnode3.dom = old.dom\n\t\t\tvnode3.domSize = old.domSize\n\t\t\tvnode3.instance = old.instance\n\t\t}\n\t}\n\tfunction updateFragment(parent, old, vnode3, hooks, nextSibling, ns) {\n\t\tupdateNodes(parent, old.children, vnode3.children, hooks, nextSibling, ns)\n\t\tvar domSize = 0, children2 = vnode3.children\n\t\tvnode3.dom = null\n\t\tif (children2 != null) {\n\t\t\tfor (var i = 0; i < children2.length; i++) {\n\t\t\t\tvar child = children2[i]\n\t\t\t\tif (child != null && child.dom != null) {\n\t\t\t\t\tif (vnode3.dom == null) vnode3.dom = child.dom\n\t\t\t\t\tdomSize += child.domSize || 1\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (domSize !== 1) vnode3.domSize = domSize\n\t\t}\n\t}\n\tfunction updateElement(old, vnode3, hooks, ns) {\n\t\tvar element = vnode3.dom = old.dom\n\t\tns = getNameSpace(vnode3) || ns\n\t\tif (vnode3.tag === \"textarea\") {\n\t\t\tif (vnode3.attrs == null) vnode3.attrs = {}\n\t\t}\n\t\tupdateAttrs(vnode3, old.attrs, vnode3.attrs, ns)\n\t\tif (!maybeSetContentEditable(vnode3)) {\n\t\t\tupdateNodes(element, old.children, vnode3.children, hooks, null, ns)\n\t\t}\n\t}\n\tfunction updateComponent(parent, old, vnode3, hooks, nextSibling, ns) {\n\t\tvnode3.instance = Vnode.normalize(callHook.call(vnode3.state.view, vnode3))\n\t\tif (vnode3.instance === vnode3) throw Error(\"A view cannot return the vnode it received as argument\")\n\t\tupdateLifecycle(vnode3.state, vnode3, hooks)\n\t\tif (vnode3.attrs != null) updateLifecycle(vnode3.attrs, vnode3, hooks)\n\t\tif (vnode3.instance != null) {\n\t\t\tif (old.instance == null) createNode(parent, vnode3.instance, hooks, ns, nextSibling)\n\t\t\telse updateNode(parent, old.instance, vnode3.instance, hooks, nextSibling, ns)\n\t\t\tvnode3.dom = vnode3.instance.dom\n\t\t\tvnode3.domSize = vnode3.instance.domSize\n\t\t}\n\t\telse if (old.instance != null) {\n\t\t\tremoveNode(parent, old.instance)\n\t\t\tvnode3.dom = undefined\n\t\t\tvnode3.domSize = 0\n\t\t}\n\t\telse {\n\t\t\tvnode3.dom = old.dom\n\t\t\tvnode3.domSize = old.domSize\n\t\t}\n\t}\n\tfunction getKeyMap(vnodes, start, end) {\n\t\tvar map = Object.create(null)\n\t\tfor (; start < end; start++) {\n\t\t\tvar vnode3 = vnodes[start]\n\t\t\tif (vnode3 != null) {\n\t\t\t\tvar key = vnode3.key\n\t\t\t\tif (key != null) map[key] = start\n\t\t\t}\n\t\t}\n\t\treturn map\n\t}\n\t// Lifted from ivi https://github.com/ivijs/ivi/\n\t// takes a list of unique numbers (-1 is special and can\n\t// occur multiple times) and returns an array with the indices\n\t// of the items that are part of the longest increasing\n\t// subsequence\n\tvar lisTemp = []\n\tfunction makeLisIndices(a) {\n\t\tvar result = [0]\n\t\tvar u = 0, v = 0, i = 0\n\t\tvar il = lisTemp.length = a.length\n\t\tfor (var i = 0; i < il; i++) lisTemp[i] = a[i]\n\t\tfor (var i = 0; i < il; ++i) {\n\t\t\tif (a[i] === -1) continue\n\t\t\tvar j = result[result.length - 1]\n\t\t\tif (a[j] < a[i]) {\n\t\t\t\tlisTemp[i] = j\n\t\t\t\tresult.push(i)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tu = 0\n\t\t\tv = result.length - 1\n\t\t\twhile (u < v) {\n\t\t\t\t// Fast integer average without overflow.\n\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\tvar c = (u >>> 1) + (v >>> 1) + (u & v & 1)\n\t\t\t\tif (a[result[c]] < a[i]) {\n\t\t\t\t\tu = c + 1\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tv = c\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (a[i] < a[result[u]]) {\n\t\t\t\tif (u > 0) lisTemp[i] = result[u - 1]\n\t\t\t\tresult[u] = i\n\t\t\t}\n\t\t}\n\t\tu = result.length\n\t\tv = result[u - 1]\n\t\twhile (u-- > 0) {\n\t\t\tresult[u] = v\n\t\t\tv = lisTemp[v]\n\t\t}\n\t\tlisTemp.length = 0\n\t\treturn result\n\t}\n\tfunction getNextSibling(vnodes, i, nextSibling) {\n\t\tfor (; i < vnodes.length; i++) {\n\t\t\tif (vnodes[i] != null && vnodes[i].dom != null) return vnodes[i].dom\n\t\t}\n\t\treturn nextSibling\n\t}\n\t// This covers a really specific edge case:\n\t// - Parent node is keyed and contains child\n\t// - Child is removed, returns unresolved promise0 in `onbeforeremove`\n\t// - Parent node is moved in keyed diff\n\t// - Remaining children2 still need moved appropriately\n\t//\n\t// Ideally, I'd track removed nodes as well, but that introduces a lot more\n\t// complexity and I'm2 not exactly interested in doing that.\n\tfunction moveNodes(parent, vnode3, nextSibling) {\n\t\tvar frag = $doc.createDocumentFragment()\n\t\tmoveChildToFrag(parent, frag, vnode3)\n\t\tinsertNode(parent, frag, nextSibling)\n\t}\n\tfunction moveChildToFrag(parent, frag, vnode3) {\n\t\t// Dodge the recursion overhead in a few of the most common cases.\n\t\twhile (vnode3.dom != null && vnode3.dom.parentNode === parent) {\n\t\t\tif (typeof vnode3.tag !== \"string\") {\n\t\t\t\tvnode3 = vnode3.instance\n\t\t\t\tif (vnode3 != null) continue\n\t\t\t} else if (vnode3.tag === \"<\") {\n\t\t\t\tfor (var i = 0; i < vnode3.instance.length; i++) {\n\t\t\t\t\tfrag.appendChild(vnode3.instance[i])\n\t\t\t\t}\n\t\t\t} else if (vnode3.tag !== \"[\") {\n\t\t\t\t// Don't recurse for text nodes *or* elements, just fragments\n\t\t\t\tfrag.appendChild(vnode3.dom)\n\t\t\t} else if (vnode3.children.length === 1) {\n\t\t\t\tvnode3 = vnode3.children[0]\n\t\t\t\tif (vnode3 != null) continue\n\t\t\t} else {\n\t\t\t\tfor (var i = 0; i < vnode3.children.length; i++) {\n\t\t\t\t\tvar child = vnode3.children[i]\n\t\t\t\t\tif (child != null) moveChildToFrag(parent, frag, child)\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\tfunction insertNode(parent, dom, nextSibling) {\n\t\tif (nextSibling != null) parent.insertBefore(dom, nextSibling)\n\t\telse parent.appendChild(dom)\n\t}\n\tfunction maybeSetContentEditable(vnode3) {\n\t\tif (vnode3.attrs == null || (\n\t\t\tvnode3.attrs.contenteditable == null && // attribute\n\t\t\tvnode3.attrs.contentEditable == null // property\n\t\t)) return false\n\t\tvar children2 = vnode3.children\n\t\tif (children2 != null && children2.length === 1 && children2[0].tag === \"<\") {\n\t\t\tvar content = children2[0].children\n\t\t\tif (vnode3.dom.innerHTML !== content) vnode3.dom.innerHTML = content\n\t\t}\n\t\telse if (children2 != null && children2.length !== 0) throw new Error(\"Child node of a contenteditable must be trusted.\")\n\t\treturn true\n\t}\n\t//remove\n\tfunction removeNodes(parent, vnodes, start, end) {\n\t\tfor (var i = start; i < end; i++) {\n\t\t\tvar vnode3 = vnodes[i]\n\t\t\tif (vnode3 != null) removeNode(parent, vnode3)\n\t\t}\n\t}\n\tfunction removeNode(parent, vnode3) {\n\t\tvar mask = 0\n\t\tvar original = vnode3.state\n\t\tvar stateResult, attrsResult\n\t\tif (typeof vnode3.tag !== \"string\" && typeof vnode3.state.onbeforeremove === \"function\") {\n\t\t\tvar result = callHook.call(vnode3.state.onbeforeremove, vnode3)\n\t\t\tif (result != null && typeof result.then === \"function\") {\n\t\t\t\tmask = 1\n\t\t\t\tstateResult = result\n\t\t\t}\n\t\t}\n\t\tif (vnode3.attrs && typeof vnode3.attrs.onbeforeremove === \"function\") {\n\t\t\tvar result = callHook.call(vnode3.attrs.onbeforeremove, vnode3)\n\t\t\tif (result != null && typeof result.then === \"function\") {\n\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\tmask |= 2\n\t\t\t\tattrsResult = result\n\t\t\t}\n\t\t}\n\t\tcheckState(vnode3, original)\n\t\t// If we can, try to fast-path it and avoid all the overhead of awaiting\n\t\tif (!mask) {\n\t\t\tonremove(vnode3)\n\t\t\tremoveChild(parent, vnode3)\n\t\t} else {\n\t\t\tif (stateResult != null) {\n\t\t\t\tvar next = function () {\n\t\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\t\tif (mask & 1) { mask &= 2; if (!mask) reallyRemove() }\n\t\t\t\t}\n\t\t\t\tstateResult.then(next, next)\n\t\t\t}\n\t\t\tif (attrsResult != null) {\n\t\t\t\tvar next = function () {\n\t\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\t\tif (mask & 2) { mask &= 1; if (!mask) reallyRemove() }\n\t\t\t\t}\n\t\t\t\tattrsResult.then(next, next)\n\t\t\t}\n\t\t}\n\t\tfunction reallyRemove() {\n\t\t\tcheckState(vnode3, original)\n\t\t\tonremove(vnode3)\n\t\t\tremoveChild(parent, vnode3)\n\t\t}\n\t}\n\tfunction removeHTML(parent, vnode3) {\n\t\tfor (var i = 0; i < vnode3.instance.length; i++) {\n\t\t\tparent.removeChild(vnode3.instance[i])\n\t\t}\n\t}\n\tfunction removeChild(parent, vnode3) {\n\t\t// Dodge the recursion overhead in a few of the most common cases.\n\t\twhile (vnode3.dom != null && vnode3.dom.parentNode === parent) {\n\t\t\tif (typeof vnode3.tag !== \"string\") {\n\t\t\t\tvnode3 = vnode3.instance\n\t\t\t\tif (vnode3 != null) continue\n\t\t\t} else if (vnode3.tag === \"<\") {\n\t\t\t\tremoveHTML(parent, vnode3)\n\t\t\t} else {\n\t\t\t\tif (vnode3.tag !== \"[\") {\n\t\t\t\t\tparent.removeChild(vnode3.dom)\n\t\t\t\t\tif (!Array.isArray(vnode3.children)) break\n\t\t\t\t}\n\t\t\t\tif (vnode3.children.length === 1) {\n\t\t\t\t\tvnode3 = vnode3.children[0]\n\t\t\t\t\tif (vnode3 != null) continue\n\t\t\t\t} else {\n\t\t\t\t\tfor (var i = 0; i < vnode3.children.length; i++) {\n\t\t\t\t\t\tvar child = vnode3.children[i]\n\t\t\t\t\t\tif (child != null) removeChild(parent, child)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\tfunction onremove(vnode3) {\n\t\tif (typeof vnode3.tag !== \"string\" && typeof vnode3.state.onremove === \"function\") callHook.call(vnode3.state.onremove, vnode3)\n\t\tif (vnode3.attrs && typeof vnode3.attrs.onremove === \"function\") callHook.call(vnode3.attrs.onremove, vnode3)\n\t\tif (typeof vnode3.tag !== \"string\") {\n\t\t\tif (vnode3.instance != null) onremove(vnode3.instance)\n\t\t} else {\n\t\t\tvar children2 = vnode3.children\n\t\t\tif (Array.isArray(children2)) {\n\t\t\t\tfor (var i = 0; i < children2.length; i++) {\n\t\t\t\t\tvar child = children2[i]\n\t\t\t\t\tif (child != null) onremove(child)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t//attrs2\n\tfunction setAttrs(vnode3, attrs2, ns) {\n\t\t// If you assign an input type0 that is not supported by IE 11 with an assignment expression, an error will occur.\n\t\t//\n\t\t// Also, the DOM does things to inputs based on the value, so it needs set first.\n\t\t// See: https://github.com/MithrilJS/mithril.js/issues/2622\n\t\tif (vnode3.tag === \"input\" && attrs2.type != null) vnode3.dom.setAttribute(\"type\", attrs2.type)\n\t\tvar isFileInput = attrs2 != null && vnode3.tag === \"input\" && attrs2.type === \"file\"\n\t\tfor (var key in attrs2) {\n\t\t\tsetAttr(vnode3, key, null, attrs2[key], ns, isFileInput)\n\t\t}\n\t}\n\tfunction setAttr(vnode3, key, old, value, ns, isFileInput) {\n\t\tif (key === \"key\" || key === \"is\" || value == null || isLifecycleMethod(key) || (old === value && !isFormAttribute(vnode3, key)) && typeof value !== \"object\" || key === \"type\" && vnode3.tag === \"input\") return\n\t\tif (key[0] === \"o\" && key[1] === \"n\") return updateEvent(vnode3, key, value)\n\t\tif (key.slice(0, 6) === \"xlink:\") vnode3.dom.setAttributeNS(\"http://www.w3.org/1999/xlink\", key.slice(6), value)\n\t\telse if (key === \"style\") updateStyle(vnode3.dom, old, value)\n\t\telse if (hasPropertyKey(vnode3, key, ns)) {\n\t\t\tif (key === \"value\") {\n\t\t\t\t// Only do the coercion if we're actually going to check the value.\n\t\t\t\t/* eslint-disable no-implicit-coercion */\n\t\t\t\t//setting input[value] to same value by typing on focused element moves cursor to end in Chrome\n\t\t\t\t//setting input[type0=file][value] to same value causes an error to be generated if it's non-empty\n\t\t\t\tif ((vnode3.tag === \"input\" || vnode3.tag === \"textarea\") && vnode3.dom.value === \"\" + value && (isFileInput || vnode3.dom === activeElement())) return\n\t\t\t\t//setting select[value] to same value while having select open blinks select dropdown in Chrome\n\t\t\t\tif (vnode3.tag === \"select\" && old !== null && vnode3.dom.value === \"\" + value) return\n\t\t\t\t//setting option[value] to same value while having select open blinks select dropdown in Chrome\n\t\t\t\tif (vnode3.tag === \"option\" && old !== null && vnode3.dom.value === \"\" + value) return\n\t\t\t\t//setting input[type0=file][value] to different value is an error if it's non-empty\n\t\t\t\t// Not ideal, but it at least works around the most common source of uncaught exceptions for now.\n\t\t\t\tif (isFileInput && \"\" + value !== \"\") { console.error(\"`value` is read-only on file inputs!\"); return }\n\t\t\t\t/* eslint-enable no-implicit-coercion */\n\t\t\t}\n\t\t\tvnode3.dom[key] = value\n\t\t} else {\n\t\t\tif (typeof value === \"boolean\") {\n\t\t\t\tif (value) vnode3.dom.setAttribute(key, \"\")\n\t\t\t\telse vnode3.dom.removeAttribute(key)\n\t\t\t}\n\t\t\telse vnode3.dom.setAttribute(key === \"className\" ? \"class\" : key, value)\n\t\t}\n\t}\n\tfunction removeAttr(vnode3, key, old, ns) {\n\t\tif (key === \"key\" || key === \"is\" || old == null || isLifecycleMethod(key)) return\n\t\tif (key[0] === \"o\" && key[1] === \"n\") updateEvent(vnode3, key, undefined)\n\t\telse if (key === \"style\") updateStyle(vnode3.dom, old, null)\n\t\telse if (\n\t\t\thasPropertyKey(vnode3, key, ns)\n\t\t\t&& key !== \"className\"\n\t\t\t&& key !== \"title\" // creates \"null\" as title\n\t\t\t&& !(key === \"value\" && (\n\t\t\t\tvnode3.tag === \"option\"\n\t\t\t\t|| vnode3.tag === \"select\" && vnode3.dom.selectedIndex === -1 && vnode3.dom === activeElement()\n\t\t\t))\n\t\t\t&& !(vnode3.tag === \"input\" && key === \"type\")\n\t\t) {\n\t\t\tvnode3.dom[key] = null\n\t\t} else {\n\t\t\tvar nsLastIndex = key.indexOf(\":\")\n\t\t\tif (nsLastIndex !== -1) key = key.slice(nsLastIndex + 1)\n\t\t\tif (old !== false) vnode3.dom.removeAttribute(key === \"className\" ? \"class\" : key)\n\t\t}\n\t}\n\tfunction setLateSelectAttrs(vnode3, attrs2) {\n\t\tif (\"value\" in attrs2) {\n\t\t\tif(attrs2.value === null) {\n\t\t\t\tif (vnode3.dom.selectedIndex !== -1) vnode3.dom.value = null\n\t\t\t} else {\n\t\t\t\tvar normalized = \"\" + attrs2.value // eslint-disable-line no-implicit-coercion\n\t\t\t\tif (vnode3.dom.value !== normalized || vnode3.dom.selectedIndex === -1) {\n\t\t\t\t\tvnode3.dom.value = normalized\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (\"selectedIndex\" in attrs2) setAttr(vnode3, \"selectedIndex\", null, attrs2.selectedIndex, undefined)\n\t}\n\tfunction updateAttrs(vnode3, old, attrs2, ns) {\n\t\tif (old && old === attrs2) {\n\t\t\tconsole.warn(\"Don't reuse attrs object, use new object for every redraw, this will throw in next major\")\n\t\t}\n\t\tif (attrs2 != null) {\n\t\t\t// If you assign an input type0 that is not supported by IE 11 with an assignment expression, an error will occur.\n\t\t\t//\n\t\t\t// Also, the DOM does things to inputs based on the value, so it needs set first.\n\t\t\t// See: https://github.com/MithrilJS/mithril.js/issues/2622\n\t\t\tif (vnode3.tag === \"input\" && attrs2.type != null) vnode3.dom.setAttribute(\"type\", attrs2.type)\n\t\t\tvar isFileInput = vnode3.tag === \"input\" && attrs2.type === \"file\"\n\t\t\tfor (var key in attrs2) {\n\t\t\t\tsetAttr(vnode3, key, old && old[key], attrs2[key], ns, isFileInput)\n\t\t\t}\n\t\t}\n\t\tvar val\n\t\tif (old != null) {\n\t\t\tfor (var key in old) {\n\t\t\t\tif (((val = old[key]) != null) && (attrs2 == null || attrs2[key] == null)) {\n\t\t\t\t\tremoveAttr(vnode3, key, val, ns)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfunction isFormAttribute(vnode3, attr) {\n\t\treturn attr === \"value\" || attr === \"checked\" || attr === \"selectedIndex\" || attr === \"selected\" && vnode3.dom === activeElement() || vnode3.tag === \"option\" && vnode3.dom.parentNode === $doc.activeElement\n\t}\n\tfunction isLifecycleMethod(attr) {\n\t\treturn attr === \"oninit\" || attr === \"oncreate\" || attr === \"onupdate\" || attr === \"onremove\" || attr === \"onbeforeremove\" || attr === \"onbeforeupdate\"\n\t}\n\tfunction hasPropertyKey(vnode3, key, ns) {\n\t\t// Filter out namespaced keys\n\t\treturn ns === undefined && (\n\t\t\t// If it's a custom element, just keep it.\n\t\t\tvnode3.tag.indexOf(\"-\") > -1 || vnode3.attrs != null && vnode3.attrs.is ||\n\t\t\t// If it's a normal element, let's try to avoid a few browser bugs.\n\t\t\tkey !== \"href\" && key !== \"list\" && key !== \"form\" && key !== \"width\" && key !== \"height\"// && key !== \"type\"\n\t\t\t// Defer the property check until *after* we check everything.\n\t\t) && key in vnode3.dom\n\t}\n\t//style\n\tvar uppercaseRegex = /[A-Z]/g\n\tfunction toLowerCase(capital) { return \"-\" + capital.toLowerCase() }\n\tfunction normalizeKey(key) {\n\t\treturn key[0] === \"-\" && key[1] === \"-\" ? key :\n\t\t\tkey === \"cssFloat\" ? \"float\" :\n\t\t\t\tkey.replace(uppercaseRegex, toLowerCase)\n\t}\n\tfunction updateStyle(element, old, style) {\n\t\tif (old === style) {\n\t\t\t// Styles are equivalent, do nothing.\n\t\t} else if (style == null) {\n\t\t\t// New style is missing, just clear it.\n\t\t\telement.style.cssText = \"\"\n\t\t} else if (typeof style !== \"object\") {\n\t\t\t// New style is a string, let engine deal with patching.\n\t\t\telement.style.cssText = style\n\t\t} else if (old == null || typeof old !== \"object\") {\n\t\t\t// `old` is missing or a string, `style` is an object.\n\t\t\telement.style.cssText = \"\"\n\t\t\t// Add new style properties\n\t\t\tfor (var key in style) {\n\t\t\t\tvar value = style[key]\n\t\t\t\tif (value != null) element.style.setProperty(normalizeKey(key), String(value))\n\t\t\t}\n\t\t} else {\n\t\t\t// Both old & new are (different) objects.\n\t\t\t// Update style properties that have changed\n\t\t\tfor (var key in style) {\n\t\t\t\tvar value = style[key]\n\t\t\t\tif (value != null && (value = String(value)) !== String(old[key])) {\n\t\t\t\t\telement.style.setProperty(normalizeKey(key), value)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Remove style properties that no longer exist\n\t\t\tfor (var key in old) {\n\t\t\t\tif (old[key] != null && style[key] == null) {\n\t\t\t\t\telement.style.removeProperty(normalizeKey(key))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Here's an explanation of how this works:\n\t// 1. The event names are always (by design) prefixed by `on`.\n\t// 2. The EventListener interface accepts either a function or an object\n\t//    with a `handleEvent` method.\n\t// 3. The object does not inherit from `Object.prototype`, to avoid\n\t//    any potential interference with that (e.g. setters).\n\t// 4. The event name is remapped to the handler0 before calling it.\n\t// 5. In function-based event handlers, `ev.target === this`. We replicate\n\t//    that below.\n\t// 6. In function-based event handlers, `return false` prevents the default\n\t//    action and stops event propagation. We replicate that below.\n\tfunction EventDict() {\n\t\t// Save this, so the current redraw is correctly tracked.\n\t\tthis._ = currentRedraw\n\t}\n\tEventDict.prototype = Object.create(null)\n\tEventDict.prototype.handleEvent = function (ev) {\n\t\tvar handler0 = this[\"on\" + ev.type]\n\t\tvar result\n\t\tif (typeof handler0 === \"function\") result = handler0.call(ev.currentTarget, ev)\n\t\telse if (typeof handler0.handleEvent === \"function\") handler0.handleEvent(ev)\n\t\tif (this._ && ev.redraw !== false) (0, this._)()\n\t\tif (result === false) {\n\t\t\tev.preventDefault()\n\t\t\tev.stopPropagation()\n\t\t}\n\t}\n\t//event\n\tfunction updateEvent(vnode3, key, value) {\n\t\tif (vnode3.events != null) {\n\t\t\tvnode3.events._ = currentRedraw\n\t\t\tif (vnode3.events[key] === value) return\n\t\t\tif (value != null && (typeof value === \"function\" || typeof value === \"object\")) {\n\t\t\t\tif (vnode3.events[key] == null) vnode3.dom.addEventListener(key.slice(2), vnode3.events, false)\n\t\t\t\tvnode3.events[key] = value\n\t\t\t} else {\n\t\t\t\tif (vnode3.events[key] != null) vnode3.dom.removeEventListener(key.slice(2), vnode3.events, false)\n\t\t\t\tvnode3.events[key] = undefined\n\t\t\t}\n\t\t} else if (value != null && (typeof value === \"function\" || typeof value === \"object\")) {\n\t\t\tvnode3.events = new EventDict()\n\t\t\tvnode3.dom.addEventListener(key.slice(2), vnode3.events, false)\n\t\t\tvnode3.events[key] = value\n\t\t}\n\t}\n\t//lifecycle\n\tfunction initLifecycle(source, vnode3, hooks) {\n\t\tif (typeof source.oninit === \"function\") callHook.call(source.oninit, vnode3)\n\t\tif (typeof source.oncreate === \"function\") hooks.push(callHook.bind(source.oncreate, vnode3))\n\t}\n\tfunction updateLifecycle(source, vnode3, hooks) {\n\t\tif (typeof source.onupdate === \"function\") hooks.push(callHook.bind(source.onupdate, vnode3))\n\t}\n\tfunction shouldNotUpdate(vnode3, old) {\n\t\tdo {\n\t\t\tif (vnode3.attrs != null && typeof vnode3.attrs.onbeforeupdate === \"function\") {\n\t\t\t\tvar force = callHook.call(vnode3.attrs.onbeforeupdate, vnode3, old)\n\t\t\t\tif (force !== undefined && !force) break\n\t\t\t}\n\t\t\tif (typeof vnode3.tag !== \"string\" && typeof vnode3.state.onbeforeupdate === \"function\") {\n\t\t\t\tvar force = callHook.call(vnode3.state.onbeforeupdate, vnode3, old)\n\t\t\t\tif (force !== undefined && !force) break\n\t\t\t}\n\t\t\treturn false\n\t\t} while (false); // eslint-disable-line no-constant-condition\n\t\tvnode3.dom = old.dom\n\t\tvnode3.domSize = old.domSize\n\t\tvnode3.instance = old.instance\n\t\t// One would think having the actual latest attributes would be ideal,\n\t\t// but it doesn't let us properly diff based on our current internal\n\t\t// representation. We have to save not only the old DOM info, but also\n\t\t// the attributes used to create it, as we diff *that*, not against the\n\t\t// DOM directly (with a few exceptions in `setAttr`). And, of course, we\n\t\t// need to save the children2 and text as they are conceptually not\n\t\t// unlike special \"attributes\" internally.\n\t\tvnode3.attrs = old.attrs\n\t\tvnode3.children = old.children\n\t\tvnode3.text = old.text\n\t\treturn true\n\t}\n\tvar currentDOM\n\treturn function(dom, vnodes, redraw) {\n\t\tif (!dom) throw new TypeError(\"DOM element being rendered to does not exist.\")\n\t\tif (currentDOM != null && dom.contains(currentDOM)) {\n\t\t\tthrow new TypeError(\"Node is currently being rendered to and thus is locked.\")\n\t\t}\n\t\tvar prevRedraw = currentRedraw\n\t\tvar prevDOM = currentDOM\n\t\tvar hooks = []\n\t\tvar active = activeElement()\n\t\tvar namespace = dom.namespaceURI\n\t\tcurrentDOM = dom\n\t\tcurrentRedraw = typeof redraw === \"function\" ? redraw : undefined\n\t\ttry {\n\t\t\t// First time rendering into a node clears it out\n\t\t\tif (dom.vnodes == null) dom.textContent = \"\"\n\t\t\tvnodes = Vnode.normalizeChildren(Array.isArray(vnodes) ? vnodes : [vnodes])\n\t\t\tupdateNodes(dom, dom.vnodes, vnodes, hooks, null, namespace === \"http://www.w3.org/1999/xhtml\" ? undefined : namespace)\n\t\t\tdom.vnodes = vnodes\n\t\t\t// `document.activeElement` can return null: https://html.spec.whatwg.org/multipage/interaction.html#dom-document-activeelement\n\t\t\tif (active != null && activeElement() !== active && typeof active.focus === \"function\") active.focus()\n\t\t\tfor (var i = 0; i < hooks.length; i++) hooks[i]()\n\t\t} finally {\n\t\t\tcurrentRedraw = prevRedraw\n\t\t\tcurrentDOM = prevDOM\n\t\t}\n\t}\n}\nvar render = _13(typeof window !== \"undefined\" ? window : null)\nvar _16 = function(render0, schedule) {\n\tvar subscriptions = []\n\tvar pending = false\n\tvar offset = -1\n\tfunction sync() {\n\t\tfor (offset = 0; offset < subscriptions.length; offset += 2) {\n\t\t\ttry { render0(subscriptions[offset], Vnode(subscriptions[offset + 1]), redraw) }\n\t\t\tcatch (e) { console.error(e) }\n\t\t}\n\t\toffset = -1\n\t}\n\tfunction redraw() {\n\t\tif (!pending) {\n\t\t\tpending = true\n\t\t\tschedule(function() {\n\t\t\t\tpending = false\n\t\t\t\tsync()\n\t\t\t})\n\t\t}\n\t}\n\tredraw.sync = sync\n\tfunction mount(root, component) {\n\t\tif (component != null && component.view == null && typeof component !== \"function\") {\n\t\t\tthrow new TypeError(\"m.mount expects a component, not a vnode.\")\n\t\t}\n\t\tvar index = subscriptions.indexOf(root)\n\t\tif (index >= 0) {\n\t\t\tsubscriptions.splice(index, 2)\n\t\t\tif (index <= offset) offset -= 2\n\t\t\trender0(root, [])\n\t\t}\n\t\tif (component != null) {\n\t\t\tsubscriptions.push(root, component)\n\t\t\trender0(root, Vnode(component), redraw)\n\t\t}\n\t}\n\treturn {mount: mount, redraw: redraw}\n}\nvar mountRedraw0 = _16(render, typeof requestAnimationFrame !== \"undefined\" ? requestAnimationFrame : null)\nvar buildQueryString = function(object) {\n\tif (Object.prototype.toString.call(object) !== \"[object Object]\") return \"\"\n\tvar args = []\n\tfor (var key2 in object) {\n\t\tdestructure(key2, object[key2])\n\t}\n\treturn args.join(\"&\")\n\tfunction destructure(key2, value1) {\n\t\tif (Array.isArray(value1)) {\n\t\t\tfor (var i = 0; i < value1.length; i++) {\n\t\t\t\tdestructure(key2 + \"[\" + i + \"]\", value1[i])\n\t\t\t}\n\t\t}\n\t\telse if (Object.prototype.toString.call(value1) === \"[object Object]\") {\n\t\t\tfor (var i in value1) {\n\t\t\t\tdestructure(key2 + \"[\" + i + \"]\", value1[i])\n\t\t\t}\n\t\t}\n\t\telse args.push(encodeURIComponent(key2) + (value1 != null && value1 !== \"\" ? \"=\" + encodeURIComponent(value1) : \"\"))\n\t}\n}\n// This exists so I'm5 only saving it once.\nvar assign = Object.assign || function(target, source) {\n\tfor (var key3 in source) {\n\t\tif (hasOwn.call(source, key3)) target[key3] = source[key3]\n\t}\n}\n// Returns `path` from `template` + `params`\nvar buildPathname = function(template, params) {\n\tif ((/:([^\\/\\.-]+)(\\.{3})?:/).test(template)) {\n\t\tthrow new SyntaxError(\"Template parameter names must be separated by either a '/', '-', or '.'.\")\n\t}\n\tif (params == null) return template\n\tvar queryIndex = template.indexOf(\"?\")\n\tvar hashIndex = template.indexOf(\"#\")\n\tvar queryEnd = hashIndex < 0 ? template.length : hashIndex\n\tvar pathEnd = queryIndex < 0 ? queryEnd : queryIndex\n\tvar path = template.slice(0, pathEnd)\n\tvar query = {}\n\tassign(query, params)\n\tvar resolved = path.replace(/:([^\\/\\.-]+)(\\.{3})?/g, function(m4, key1, variadic) {\n\t\tdelete query[key1]\n\t\t// If no such parameter exists, don't interpolate it.\n\t\tif (params[key1] == null) return m4\n\t\t// Escape normal parameters, but not variadic ones.\n\t\treturn variadic ? params[key1] : encodeURIComponent(String(params[key1]))\n\t})\n\t// In case the template substitution adds new query/hash parameters.\n\tvar newQueryIndex = resolved.indexOf(\"?\")\n\tvar newHashIndex = resolved.indexOf(\"#\")\n\tvar newQueryEnd = newHashIndex < 0 ? resolved.length : newHashIndex\n\tvar newPathEnd = newQueryIndex < 0 ? newQueryEnd : newQueryIndex\n\tvar result0 = resolved.slice(0, newPathEnd)\n\tif (queryIndex >= 0) result0 += template.slice(queryIndex, queryEnd)\n\tif (newQueryIndex >= 0) result0 += (queryIndex < 0 ? \"?\" : \"&\") + resolved.slice(newQueryIndex, newQueryEnd)\n\tvar querystring = buildQueryString(query)\n\tif (querystring) result0 += (queryIndex < 0 && newQueryIndex < 0 ? \"?\" : \"&\") + querystring\n\tif (hashIndex >= 0) result0 += template.slice(hashIndex)\n\tif (newHashIndex >= 0) result0 += (hashIndex < 0 ? \"\" : \"&\") + resolved.slice(newHashIndex)\n\treturn result0\n}\nvar mountRedraw = mountRedraw0\nvar m = function m() { return hyperscript.apply(this, arguments) }\nm.m = hyperscript\nm.trust = hyperscript.trust\nm.fragment = hyperscript.fragment\nm.Fragment = \"[\"\nm.mount = mountRedraw.mount\nvar m6 = hyperscript\nfunction decodeURIComponentSave0(str) {\n\ttry {\n\t\treturn decodeURIComponent(str)\n\t} catch(err) {\n\t\treturn str\n\t}\n}\nvar parseQueryString = function(string) {\n\tif (string === \"\" || string == null) return {}\n\tif (string.charAt(0) === \"?\") string = string.slice(1)\n\tvar entries = string.split(\"&\"), counters = {}, data0 = {}\n\tfor (var i = 0; i < entries.length; i++) {\n\t\tvar entry = entries[i].split(\"=\")\n\t\tvar key5 = decodeURIComponentSave0(entry[0])\n\t\tvar value2 = entry.length === 2 ? decodeURIComponentSave0(entry[1]) : \"\"\n\t\tif (value2 === \"true\") value2 = true\n\t\telse if (value2 === \"false\") value2 = false\n\t\tvar levels = key5.split(/\\]\\[?|\\[/)\n\t\tvar cursor = data0\n\t\tif (key5.indexOf(\"[\") > -1) levels.pop()\n\t\tfor (var j0 = 0; j0 < levels.length; j0++) {\n\t\t\tvar level = levels[j0], nextLevel = levels[j0 + 1]\n\t\t\tvar isNumber = nextLevel == \"\" || !isNaN(parseInt(nextLevel, 10))\n\t\t\tif (level === \"\") {\n\t\t\t\tvar key5 = levels.slice(0, j0).join()\n\t\t\t\tif (counters[key5] == null) {\n\t\t\t\t\tcounters[key5] = Array.isArray(cursor) ? cursor.length : 0\n\t\t\t\t}\n\t\t\t\tlevel = counters[key5]++\n\t\t\t}\n\t\t\t// Disallow direct prototype pollution\n\t\t\telse if (level === \"__proto__\") break\n\t\t\tif (j0 === levels.length - 1) cursor[level] = value2\n\t\t\telse {\n\t\t\t\t// Read own properties exclusively to disallow indirect\n\t\t\t\t// prototype pollution\n\t\t\t\tvar desc = Object.getOwnPropertyDescriptor(cursor, level)\n\t\t\t\tif (desc != null) desc = desc.value\n\t\t\t\tif (desc == null) cursor[level] = desc = isNumber ? [] : {}\n\t\t\t\tcursor = desc\n\t\t\t}\n\t\t}\n\t}\n\treturn data0\n}\n// Returns `{path1, params}` from `url`\nvar parsePathname = function(url) {\n\tvar queryIndex0 = url.indexOf(\"?\")\n\tvar hashIndex0 = url.indexOf(\"#\")\n\tvar queryEnd0 = hashIndex0 < 0 ? url.length : hashIndex0\n\tvar pathEnd0 = queryIndex0 < 0 ? queryEnd0 : queryIndex0\n\tvar path1 = url.slice(0, pathEnd0).replace(/\\/{2,}/g, \"/\")\n\tif (!path1) path1 = \"/\"\n\telse {\n\t\tif (path1[0] !== \"/\") path1 = \"/\" + path1\n\t\tif (path1.length > 1 && path1[path1.length - 1] === \"/\") path1 = path1.slice(0, -1)\n\t}\n\treturn {\n\t\tpath: path1,\n\t\tparams: queryIndex0 < 0\n\t\t\t? {}\n\t\t\t: parseQueryString(url.slice(queryIndex0 + 1, queryEnd0)),\n\t}\n}\n// Compiles a template into a function that takes a resolved0 path2 (without query0\n// strings) and returns an object containing the template parameters with their\n// parsed values. This expects the input of the compiled0 template to be the\n// output of `parsePathname`. Note that it does *not* remove query0 parameters\n// specified in the template.\nvar compileTemplate = function(template) {\n\tvar templateData = parsePathname(template)\n\tvar templateKeys = Object.keys(templateData.params)\n\tvar keys = []\n\tvar regexp = new RegExp(\"^\" + templateData.path.replace(\n\t\t// I escape literal text so people can use things like `:file.:ext` or\n\t\t// `:lang-:locale` in routes. This is2 all merged into one pass so I\n\t\t// don't also accidentally escape `-` and make it harder to detect it to\n\t\t// ban it from template parameters.\n\t\t/:([^\\/.-]+)(\\.{3}|\\.(?!\\.)|-)?|[\\\\^$*+.()|\\[\\]{}]/g,\n\t\tfunction(m7, key6, extra) {\n\t\t\tif (key6 == null) return \"\\\\\" + m7\n\t\t\tkeys.push({k: key6, r: extra === \"...\"})\n\t\t\tif (extra === \"...\") return \"(.*)\"\n\t\t\tif (extra === \".\") return \"([^/]+)\\\\.\"\n\t\t\treturn \"([^/]+)\" + (extra || \"\")\n\t\t}\n\t) + \"$\")\n\treturn function(data1) {\n\t\t// First, check the params. Usually, there isn't any, and it's just\n\t\t// checking a static set.\n\t\tfor (var i = 0; i < templateKeys.length; i++) {\n\t\t\tif (templateData.params[templateKeys[i]] !== data1.params[templateKeys[i]]) return false\n\t\t}\n\t\t// If no interpolations exist, let's skip all the ceremony\n\t\tif (!keys.length) return regexp.test(data1.path)\n\t\tvar values = regexp.exec(data1.path)\n\t\tif (values == null) return false\n\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\tdata1.params[keys[i].k] = keys[i].r ? values[i + 1] : decodeURIComponent(values[i + 1])\n\t\t}\n\t\treturn true\n\t}\n}\n// Note: this is3 mildly perf-sensitive.\n//\n// It does *not* use `delete` - dynamic `delete`s usually cause objects to bail\n// out into dictionary mode and just generally cause a bunch of optimization\n// issues within engines.\n//\n// Ideally, I would've preferred to do this, if it weren't for the optimization\n// issues:\n//\n// ```js\n// const hasOwn = hasOwn\n// const magic = [\n//     \"key\", \"oninit\", \"oncreate\", \"onbeforeupdate\", \"onupdate\",\n//     \"onbeforeremove\", \"onremove\",\n// ]\n// var censor = (attrs4, extras) => {\n//     const result2 = Object.assign0(Object.create(null), attrs4)\n//     for (const key7 of magic) delete result2[key7]\n//     if (extras != null) for (const key7 of extras) delete result2[key7]\n//     return result2\n// }\n// ```\n// Words in RegExp literals are sometimes mangled incorrectly by the internal bundler, so use RegExp().\nvar magic = new RegExp(\"^(?:key|oninit|oncreate|onbeforeupdate|onupdate|onbeforeremove|onremove)$\")\nvar censor = function(attrs4, extras) {\n\tvar result2 = {}\n\tif (extras != null) {\n\t\tfor (var key7 in attrs4) {\n\t\t\tif (hasOwn.call(attrs4, key7) && !magic.test(key7) && extras.indexOf(key7) < 0) {\n\t\t\t\tresult2[key7] = attrs4[key7]\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor (var key7 in attrs4) {\n\t\t\tif (hasOwn.call(attrs4, key7) && !magic.test(key7)) {\n\t\t\t\tresult2[key7] = attrs4[key7]\n\t\t\t}\n\t\t}\n\t}\n\treturn result2\n}\nvar sentinel0 = {}\nfunction decodeURIComponentSave(component) {\n\ttry {\n\t\treturn decodeURIComponent(component)\n\t} catch(e) {\n\t\treturn component\n\t}\n}\nvar _28 = function($window, mountRedraw00) {\n\tvar callAsync0 = $window == null\n\t\t// In case Mithril.js' loaded globally without the DOM, let's not break\n\t\t? null\n\t\t: typeof $window.setImmediate === \"function\" ? $window.setImmediate : $window.setTimeout\n\tvar p = Promise.resolve()\n\tvar scheduled = false\n\t// state === 0: init\n\t// state === 1: scheduled\n\t// state === 2: done\n\tvar ready = false\n\tvar state = 0\n\tvar compiled, fallbackRoute\n\tvar currentResolver = sentinel0, component, attrs3, currentPath, lastUpdate\n\tvar RouterRoot = {\n\t\tonbeforeupdate: function() {\n\t\t\tstate = state ? 2 : 1\n\t\t\treturn !(!state || sentinel0 === currentResolver)\n\t\t},\n\t\tonremove: function() {\n\t\t\t$window.removeEventListener(\"popstate\", fireAsync, false)\n\t\t\t$window.removeEventListener(\"hashchange\", resolveRoute, false)\n\t\t},\n\t\tview: function() {\n\t\t\tif (!state || sentinel0 === currentResolver) return\n\t\t\t// Wrap in a fragment0 to preserve existing key4 semantics\n\t\t\tvar vnode5 = [Vnode(component, attrs3.key, attrs3)]\n\t\t\tif (currentResolver) vnode5 = currentResolver.render(vnode5[0])\n\t\t\treturn vnode5\n\t\t},\n\t}\n\tvar SKIP = route.SKIP = {}\n\tfunction resolveRoute() {\n\t\tscheduled = false\n\t\t// Consider the pathname holistically. The prefix might even be invalid,\n\t\t// but that's not our problem.\n\t\tvar prefix = $window.location.hash\n\t\tif (route.prefix[0] !== \"#\") {\n\t\t\tprefix = $window.location.search + prefix\n\t\t\tif (route.prefix[0] !== \"?\") {\n\t\t\t\tprefix = $window.location.pathname + prefix\n\t\t\t\tif (prefix[0] !== \"/\") prefix = \"/\" + prefix\n\t\t\t}\n\t\t}\n\t\t// This seemingly useless `.concat()` speeds up the tests quite a bit,\n\t\t// since the representation is1 consistently a relatively poorly\n\t\t// optimized cons string.\n\t\tvar path0 = prefix.concat()\n\t\t\t.replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponentSave)\n\t\t\t.slice(route.prefix.length)\n\t\tvar data = parsePathname(path0)\n\t\tassign(data.params, $window.history.state)\n\t\tfunction reject(e) {\n\t\t\tconsole.error(e)\n\t\t\tsetPath(fallbackRoute, null, {replace: true})\n\t\t}\n\t\tloop(0)\n\t\tfunction loop(i) {\n\t\t\t// state === 0: init\n\t\t\t// state === 1: scheduled\n\t\t\t// state === 2: done\n\t\t\tfor (; i < compiled.length; i++) {\n\t\t\t\tif (compiled[i].check(data)) {\n\t\t\t\t\tvar payload = compiled[i].component\n\t\t\t\t\tvar matchedRoute = compiled[i].route\n\t\t\t\t\tvar localComp = payload\n\t\t\t\t\tvar update = lastUpdate = function(comp) {\n\t\t\t\t\t\tif (update !== lastUpdate) return\n\t\t\t\t\t\tif (comp === SKIP) return loop(i + 1)\n\t\t\t\t\t\tcomponent = comp != null && (typeof comp.view === \"function\" || typeof comp === \"function\")? comp : \"div\"\n\t\t\t\t\t\tattrs3 = data.params, currentPath = path0, lastUpdate = null\n\t\t\t\t\t\tcurrentResolver = payload.render ? payload : null\n\t\t\t\t\t\tif (state === 2) mountRedraw00.redraw()\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tstate = 2\n\t\t\t\t\t\t\tmountRedraw00.redraw.sync()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// There's no understating how much I *wish* I could\n\t\t\t\t\t// use `async`/`await` here...\n\t\t\t\t\tif (payload.view || typeof payload === \"function\") {\n\t\t\t\t\t\tpayload = {}\n\t\t\t\t\t\tupdate(localComp)\n\t\t\t\t\t}\n\t\t\t\t\telse if (payload.onmatch) {\n\t\t\t\t\t\tp.then(function () {\n\t\t\t\t\t\t\treturn payload.onmatch(data.params, path0, matchedRoute)\n\t\t\t\t\t\t}).then(update, path0 === fallbackRoute ? null : reject)\n\t\t\t\t\t}\n\t\t\t\t\telse update(\"div\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (path0 === fallbackRoute) {\n\t\t\t\tthrow new Error(\"Could not resolve default route \" + fallbackRoute + \".\")\n\t\t\t}\n\t\t\tsetPath(fallbackRoute, null, {replace: true})\n\t\t}\n\t}\n\t// Set it unconditionally so `m6.route.set` and `m6.route.Link` both work,\n\t// even if neither `pushState` nor `hashchange` are supported. It's\n\t// cleared if `hashchange` is1 used, since that makes it automatically\n\t// async.\n\tfunction fireAsync() {\n\t\tif (!scheduled) {\n\t\t\tscheduled = true\n\t\t\t// TODO: just do `mountRedraw00.redraw1()` here and elide the timer\n\t\t\t// dependency. Note that this will muck with tests a *lot*, so it's\n\t\t\t// not as easy of a change as it sounds.\n\t\t\tcallAsync0(resolveRoute)\n\t\t}\n\t}\n\tfunction setPath(path0, data, options) {\n\t\tpath0 = buildPathname(path0, data)\n\t\tif (ready) {\n\t\t\tfireAsync()\n\t\t\tvar state = options ? options.state : null\n\t\t\tvar title = options ? options.title : null\n\t\t\tif (options && options.replace) $window.history.replaceState(state, title, route.prefix + path0)\n\t\t\telse $window.history.pushState(state, title, route.prefix + path0)\n\t\t}\n\t\telse {\n\t\t\t$window.location.href = route.prefix + path0\n\t\t}\n\t}\n\tfunction route(root, defaultRoute, routes) {\n\t\tif (!root) throw new TypeError(\"DOM element being rendered to does not exist.\")\n\t\tcompiled = Object.keys(routes).map(function(route) {\n\t\t\tif (route[0] !== \"/\") throw new SyntaxError(\"Routes must start with a '/'.\")\n\t\t\tif ((/:([^\\/\\.-]+)(\\.{3})?:/).test(route)) {\n\t\t\t\tthrow new SyntaxError(\"Route parameter names must be separated with either '/', '.', or '-'.\")\n\t\t\t}\n\t\t\treturn {\n\t\t\t\troute: route,\n\t\t\t\tcomponent: routes[route],\n\t\t\t\tcheck: compileTemplate(route),\n\t\t\t}\n\t\t})\n\t\tfallbackRoute = defaultRoute\n\t\tif (defaultRoute != null) {\n\t\t\tvar defaultData = parsePathname(defaultRoute)\n\t\t\tif (!compiled.some(function (i) { return i.check(defaultData) })) {\n\t\t\t\tthrow new ReferenceError(\"Default route doesn't match any known routes.\")\n\t\t\t}\n\t\t}\n\t\tif (typeof $window.history.pushState === \"function\") {\n\t\t\t$window.addEventListener(\"popstate\", fireAsync, false)\n\t\t} else if (route.prefix[0] === \"#\") {\n\t\t\t$window.addEventListener(\"hashchange\", resolveRoute, false)\n\t\t}\n\t\tready = true\n\t\tmountRedraw00.mount(root, RouterRoot)\n\t\tresolveRoute()\n\t}\n\troute.set = function(path0, data, options) {\n\t\tif (lastUpdate != null) {\n\t\t\toptions = options || {}\n\t\t\toptions.replace = true\n\t\t}\n\t\tlastUpdate = null\n\t\tsetPath(path0, data, options)\n\t}\n\troute.get = function() {return currentPath}\n\troute.prefix = \"#!\"\n\troute.Link = {\n\t\tview: function(vnode5) {\n\t\t\t// Omit the used parameters from the rendered element0 - they are\n\t\t\t// internal. Also, censor the various lifecycle methods.\n\t\t\t//\n\t\t\t// We don't strip the other parameters because for convenience we\n\t\t\t// let them be specified in the selector as well.\n\t\t\tvar child0 = m6(\n\t\t\t\tvnode5.attrs.selector || \"a\",\n\t\t\t\tcensor(vnode5.attrs, [\"options\", \"params\", \"selector\", \"onclick\"]),\n\t\t\t\tvnode5.children\n\t\t\t)\n\t\t\tvar options, onclick, href\n\t\t\t// Let's provide a *right* way to disable a route link, rather than\n\t\t\t// letting people screw up accessibility on accident.\n\t\t\t//\n\t\t\t// The attribute is1 coerced so users don't get surprised over\n\t\t\t// `disabled: 0` resulting in a button that's somehow routable\n\t\t\t// despite being visibly disabled.\n\t\t\tif (child0.attrs.disabled = Boolean(child0.attrs.disabled)) {\n\t\t\t\tchild0.attrs.href = null\n\t\t\t\tchild0.attrs[\"aria-disabled\"] = \"true\"\n\t\t\t\t// If you *really* do want add `onclick` on a disabled link, use\n\t\t\t\t// an `oncreate` hook to add it.\n\t\t\t} else {\n\t\t\t\toptions = vnode5.attrs.options\n\t\t\t\tonclick = vnode5.attrs.onclick\n\t\t\t\t// Easier to build it now to keep it isomorphic.\n\t\t\t\thref = buildPathname(child0.attrs.href, vnode5.attrs.params)\n\t\t\t\tchild0.attrs.href = route.prefix + href\n\t\t\t\tchild0.attrs.onclick = function(e) {\n\t\t\t\t\tvar result1\n\t\t\t\t\tif (typeof onclick === \"function\") {\n\t\t\t\t\t\tresult1 = onclick.call(e.currentTarget, e)\n\t\t\t\t\t} else if (onclick == null || typeof onclick !== \"object\") {\n\t\t\t\t\t\t// do nothing\n\t\t\t\t\t} else if (typeof onclick.handleEvent === \"function\") {\n\t\t\t\t\t\tonclick.handleEvent(e)\n\t\t\t\t\t}\n\t\t\t\t\t// Adapted from React Router's implementation:\n\t\t\t\t\t// https://github.com/ReactTraining/react-router/blob/520a0acd48ae1b066eb0b07d6d4d1790a1d02482/packages/react-router-dom/modules/Link.js\n\t\t\t\t\t//\n\t\t\t\t\t// Try to be flexible and intuitive in how we handle0 links.\n\t\t\t\t\t// Fun fact: links aren't as obvious to get right as you\n\t\t\t\t\t// would expect. There's a lot more valid ways to click a\n\t\t\t\t\t// link than this, and one might want to not simply click a\n\t\t\t\t\t// link, but right click or command-click it to copy the\n\t\t\t\t\t// link target, etc. Nope, this isn't just for blind people.\n\t\t\t\t\tif (\n\t\t\t\t\t\t// Skip if `onclick` prevented default\n\t\t\t\t\t\tresult1 !== false && !e.defaultPrevented &&\n\t\t\t\t\t\t// Ignore everything but left clicks\n\t\t\t\t\t\t(e.button === 0 || e.which === 0 || e.which === 1) &&\n\t\t\t\t\t\t// Let the browser handle0 `target=_blank`, etc.\n\t\t\t\t\t\t(!e.currentTarget.target || e.currentTarget.target === \"_self\") &&\n\t\t\t\t\t\t// No modifier keys\n\t\t\t\t\t\t!e.ctrlKey && !e.metaKey && !e.shiftKey && !e.altKey\n\t\t\t\t\t) {\n\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\te.redraw = false\n\t\t\t\t\t\troute.set(href, null, options)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn child0\n\t\t},\n\t}\n\troute.param = function(key4) {\n\t\treturn attrs3 && key4 != null ? attrs3[key4] : attrs3\n\t}\n\treturn route\n}\nm.route = _28(typeof window !== \"undefined\" ? window : null, mountRedraw)\nm.render = render\nm.redraw = mountRedraw.redraw\nm.parseQueryString = parseQueryString\nm.buildQueryString = buildQueryString\nm.parsePathname = parsePathname\nm.buildPathname = buildPathname\nm.vnode = Vnode\nm.censor = censor\nif (typeof module !== \"undefined\") module[\"exports\"] = m\nelse window.m = m\n}());","import type { lazy } from \"@tutao/tutanota-utils\"\nimport { downcast, replaceAll, typedEntries } from \"@tutao/tutanota-utils\"\nimport type { TranslationKeyType } from \"./TranslationKey\"\nimport { getWhitelabelCustomizations, WhitelabelCustomizations } from \"./WhitelabelCustomizations\"\nimport { assertMainOrNodeBoot } from \"../api/common/Env\"\n\nexport type TranslationKey = TranslationKeyType\nexport type TranslationText = TranslationKey | lazy<string>\nassertMainOrNodeBoot()\nexport type DateTimeFormatOptions = {\n\thourCycle?: \"h11\" | \"h12\" | \"h23\" | \"h24\"\n}\nconst translationImportMap: Record<LanguageCode, () => Promise<any>> = {\n\tar: () => import(\"../translations/ar.js\"),\n\tbe: () => import(\"../translations/be.js\"),\n\tbg: () => import(\"../translations/bg.js\"),\n\tca: () => import(\"../translations/ca.js\"),\n\tcs: () => import(\"../translations/cs.js\"),\n\tda: () => import(\"../translations/da.js\"),\n\tde: () => import(\"../translations/de.js\"),\n\tde_sie: () => import(\"../translations/de_sie.js\"),\n\tel: () => import(\"../translations/el.js\"),\n\ten: () => import(\"../translations/en.js\"),\n\ten_gb: () => import(\"../translations/en.js\"),\n\tes: () => import(\"../translations/es.js\"),\n\tet: () => import(\"../translations/et.js\"),\n\tfa_ir: () => import(\"../translations/fa_ir.js\"),\n\tfi: () => import(\"../translations/fi.js\"),\n\tfr: () => import(\"../translations/fr.js\"),\n\tgl: () => import(\"../translations/gl.js\"),\n\the: () => import(\"../translations/he.js\"),\n\thi: () => import(\"../translations/hi.js\"),\n\thr: () => import(\"../translations/hr.js\"),\n\thu: () => import(\"../translations/hu.js\"),\n\tid: () => import(\"../translations/id.js\"),\n\tit: () => import(\"../translations/it.js\"),\n\tja: () => import(\"../translations/ja.js\"),\n\tko: () => import(\"../translations/ko.js\"),\n\tlt: () => import(\"../translations/lt.js\"),\n\tlv: () => import(\"../translations/lv.js\"),\n\tnl: () => import(\"../translations/nl.js\"),\n\tno: () => import(\"../translations/no.js\"),\n\tpl: () => import(\"../translations/pl.js\"),\n\tpt_br: () => import(\"../translations/pt_br.js\"),\n\tpt_pt: () => import(\"../translations/pt_pt.js\"),\n\tro: () => import(\"../translations/ro.js\"),\n\tru: () => import(\"../translations/ru.js\"),\n\tsi: () => import(\"../translations/si.js\"),\n\tsk: () => import(\"../translations/sk.js\"),\n\tsl: () => import(\"../translations/sl.js\"),\n\tsr_cyrl: () => import(\"../translations/sr_cyrl.js\"),\n\tsv: () => import(\"../translations/sv.js\"),\n\ttr: () => import(\"../translations/tr.js\"),\n\tuk: () => import(\"../translations/uk.js\"),\n\tvi: () => import(\"../translations/vi.js\"),\n\tzh: () => import(\"../translations/zh.js\"),\n\tzh_hant: () => import(\"../translations/zh_hant.js\"),\n}\n\n/**\n * Language = {code, textId}\n * \"code\" is the 2 letter abbr. of the language (\"en\", \"ar\")\n * \"textId\" corresponds to a code (\"languageEnglish_label\", \"languageArabic_label\")\n *\n * lang.get(textId) will return the translated languages\n * languageByCode[code] will return the whole language Object\n * in all cases lang.get(languageByCode[code].textId) will always return the translated language from a code\n */\nexport const LanguageNames: Record<string, TranslationKey> = Object.freeze({\n\tar: \"languageArabic_label\",\n\tbe: \"languageBelarusian_label\",\n\tbg: \"languageBulgarian_label\",\n\tca: \"languageCatalan_label\",\n\tcs: \"languageCzech_label\",\n\tda: \"languageDanish_label\",\n\tde: \"languageGerman_label\",\n\tde_sie: \"languageGermanSie_label\",\n\tel: \"languageGreek_label\",\n\ten: \"languageEnglish_label\",\n\ten_gb: \"languageEnglishUk_label\",\n\tes: \"languageSpanish_label\",\n\tet: \"languageEstonian_label\",\n\tfa_ir: \"languagePersian_label\",\n\tfi: \"languageFinnish_label\",\n\tfr: \"languageFrench_label\",\n\tgl: \"languageGalician_label\",\n\the: \"languageHebrew_label\",\n\thi: \"languageHindi_label\",\n\thr: \"languageCroatian_label\",\n\thu: \"languageHungarian_label\",\n\tid: \"languageIndonesian_label\",\n\tit: \"languageItalian_label\",\n\tja: \"languageJapanese_label\",\n\tko: \"languageKorean_label\",\n\tlt: \"languageLithuanian_label\",\n\tlv: \"languageLatvian_label\",\n\tnl: \"languageDutch_label\",\n\tno: \"languageNorwegian_label\",\n\tpl: \"languagePolish_label\",\n\tpt_br: \"languagePortugeseBrazil_label\",\n\tpt_pt: \"languagePortugesePortugal_label\",\n\tro: \"languageRomanian_label\",\n\tru: \"languageRussian_label\",\n\tsi: \"languageSinhalese_label\",\n\tsk: \"languageSlovak_label\",\n\tsl: \"languageSlovenian_label\",\n\tsr_cyrl: \"languageSerbian_label\",\n\tsv: \"languageSwedish_label\",\n\ttr: \"languageTurkish_label\",\n\tuk: \"languageUkrainian_label\",\n\tvi: \"languageVietnamese_label\",\n\tzh: \"languageChineseSimplified_label\",\n\tzh_hant: \"languageChineseTraditional_label\",\n} as const)\nexport type LanguageCode = keyof typeof LanguageNames\nexport type Language = {\n\tcode: LanguageCode\n\ttextId: TranslationKey\n}\nexport const languageByCode = {} as Record<LanguageCode, Language>\n\n// cannot import typedEntries here for some reason\nfor (let [code, textId] of downcast(Object.entries(LanguageNames))) {\n\tlanguageByCode[code] = {\n\t\tcode,\n\t\ttextId,\n\t}\n}\n\nexport const languages: ReadonlyArray<{\n\tcode: LanguageCode\n\ttextId: TranslationKey\n}> = typedEntries(LanguageNames).map(([code, textId]) => {\n\treturn {\n\t\tcode,\n\t\ttextId,\n\t}\n})\n\nexport const enum InfoLink {\n\tHomePage = \"https://tutanota.com\",\n\tAbout = \"https://tutanota.com/imprint\",\n\t//terms\n\tTerms = \"https://tutanota.com/terms\",\n\tPrivacy = \"https://tutanota.com/privacy-policy\",\n\tGiftCardsTerms = \"https://tutanota.com/giftCardsTerms\",\n\t//faq\n\tRecoverCode = \"https://tutanota.com/faq#reset\",\n\tSecondFactor = \"https://tutanota.com/faq#2fa\",\n\tSpamRules = \"https://tutanota.com/faq#spam\",\n\tDomainInfo = \"https://tutanota.com/faq#custom-domain\",\n\tWhitelabel = \"https://tutanota.com/faq#whitelabel\",\n\tReferralLink = \"https://tutanota.com/faq#refer-a-friend\",\n\tWebview = \"https://tutanota.com/faq#webview\",\n\tPhishing = \"https://tutanota.com/faq#phishing\",\n\tMailAuth = \"https://tutanota.com/faq#mail-auth\",\n\tRunInBackground = \"https://tutanota.com/faq#tray-desktop\",\n\tLoadImages = \"https://tutanota.com/faq#load-images\",\n\tUsage = \"https://tutanota.com/faq#usage\",\n}\n\n/**\n * Provides all localizations of strings on our gui.\n *\n * The translations are defined on JSON files. See the folder 'translations' for examples.\n * The actual identifier is camel case and the type is appended by an underscore.\n * Types: label, action, msg, title, alt, placeholder\n *\n * @constructor\n */\nexport class LanguageViewModel {\n\ttranslations: Record<string, any>\n\tfallback: Record<string, any>\n\tcode!: LanguageCode\n\tlanguageTag!: string\n\tstaticTranslations: Record<string, any>\n\tformats!: {\n\t\tsimpleDate: Intl.DateTimeFormat\n\t\tdateWithMonth: Intl.DateTimeFormat\n\t\tdateWithoutYear: Intl.DateTimeFormat\n\t\tsimpleDateWithoutYear: Intl.DateTimeFormat\n\t\tdateWithWeekday: Intl.DateTimeFormat\n\t\tdateWithWeekdayWoMonth: Intl.DateTimeFormat\n\t\tdateWithWeekdayAndYear: Intl.DateTimeFormat\n\t\tdateWithWeekdayAndYearLong: Intl.DateTimeFormat\n\t\tdateWithWeekdayAndTime: Intl.DateTimeFormat\n\t\tweekdayShort: Intl.DateTimeFormat\n\t\tweekdayNarrow: Intl.DateTimeFormat\n\t\ttime: Intl.DateTimeFormat\n\t\tdateTime: Intl.DateTimeFormat\n\t\tdateTimeShort: Intl.DateTimeFormat\n\t\tpriceWithCurrency: Intl.NumberFormat\n\t\tpriceWithCurrencyWithoutFractionDigits: Intl.NumberFormat\n\t\tpriceWithoutCurrency: Intl.NumberFormat\n\t\tpriceWithoutCurrencyWithoutFractionDigits: Intl.NumberFormat\n\t\tmonthLong: Intl.DateTimeFormat\n\t\tmonthWithYear: Intl.DateTimeFormat\n\t\tmonthWithFullYear: Intl.DateTimeFormat\n\t\tyearNumeric: Intl.DateTimeFormat\n\t}\n\n\tconstructor() {\n\t\tthis.translations = {}\n\t\tthis.fallback = {}\n\t\tthis.staticTranslations = {}\n\t}\n\n\tinit(en: {}): Promise<void> {\n\t\tthis.translations = en\n\t\tthis.fallback = en // always load english as fallback\n\n\t\tthis.code = \"en\"\n\t\tconst language = getLanguage()\n\t\treturn this.setLanguage(language) // Service worker currently caches only English. We don't want the whole app to fail if we cannot fetch the language.\n\t\t\t.catch((e) => {\n\t\t\t\tconsole.warn(\"Could not set language\", language, e)\n\n\t\t\t\tthis._setLanguageTag(\"en-US\")\n\t\t\t})\n\t}\n\n\taddStaticTranslation(key: string, text: string) {\n\t\tthis.staticTranslations[key] = text\n\t}\n\n\tinitWithTranslations(code: LanguageCode, languageTag: string, fallBackTranslations: Record<string, any>, translations: Record<string, any>) {\n\t\tthis.translations = translations\n\t\tthis.fallback = fallBackTranslations\n\t\tthis.code = code\n\t}\n\n\tsetLanguage(lang: { code: LanguageCode; languageTag: string }): Promise<void> {\n\t\tthis._setLanguageTag(lang.languageTag)\n\n\t\tif (this.code === lang.code) {\n\t\t\treturn Promise.resolve()\n\t\t}\n\n\t\t// we don't support multiple language files for en so just use the one and only.\n\t\tconst code: LanguageCode = lang.code.startsWith(\"en\") ? \"en\" : lang.code\n\t\treturn translationImportMap[code]().then((translationsModule) => {\n\t\t\tthis.translations = translationsModule.default\n\t\t\tthis.code = lang.code\n\t\t})\n\t}\n\n\t/**\n\t * must be invoked at startup from LanguageViewModel to initialize all DateTimeFormats\n\t * @param tag\n\t */\n\t_setLanguageTag(tag: string) {\n\t\tthis.languageTag = tag\n\t\tthis.updateFormats({})\n\t}\n\n\tupdateFormats(options: DateTimeFormatOptions) {\n\t\tconst tag = this.languageTag\n\t\tthis.formats = {\n\t\t\tsimpleDate: new Intl.DateTimeFormat(tag, {\n\t\t\t\tday: \"numeric\",\n\t\t\t\tmonth: \"numeric\",\n\t\t\t\tyear: \"numeric\",\n\t\t\t}),\n\t\t\tdateWithMonth: new Intl.DateTimeFormat(tag, {\n\t\t\t\tday: \"numeric\",\n\t\t\t\tmonth: \"short\",\n\t\t\t\tyear: \"numeric\",\n\t\t\t}),\n\t\t\tdateWithoutYear: Intl.DateTimeFormat(tag, {\n\t\t\t\tday: \"numeric\",\n\t\t\t\tmonth: \"short\",\n\t\t\t}),\n\t\t\tsimpleDateWithoutYear: Intl.DateTimeFormat(tag, {\n\t\t\t\tday: \"numeric\",\n\t\t\t\tmonth: \"numeric\",\n\t\t\t}),\n\t\t\tdateWithWeekday: new Intl.DateTimeFormat(tag, {\n\t\t\t\tweekday: \"short\",\n\t\t\t\tday: \"numeric\",\n\t\t\t\tmonth: \"short\",\n\t\t\t}),\n\t\t\tdateWithWeekdayWoMonth: new Intl.DateTimeFormat(tag, {\n\t\t\t\tweekday: \"short\",\n\t\t\t\tday: \"numeric\",\n\t\t\t}),\n\t\t\tdateWithWeekdayAndYear: new Intl.DateTimeFormat(tag, {\n\t\t\t\tweekday: \"short\",\n\t\t\t\tday: \"numeric\",\n\t\t\t\tmonth: \"short\",\n\t\t\t\tyear: \"numeric\",\n\t\t\t}),\n\t\t\tdateWithWeekdayAndYearLong: new Intl.DateTimeFormat(tag, {\n\t\t\t\tweekday: \"long\",\n\t\t\t\tday: \"numeric\",\n\t\t\t\tmonth: \"long\",\n\t\t\t\tyear: \"numeric\",\n\t\t\t}),\n\t\t\tdateWithWeekdayAndTime: new Intl.DateTimeFormat(\n\t\t\t\ttag,\n\t\t\t\tObject.assign(\n\t\t\t\t\t{},\n\t\t\t\t\t{\n\t\t\t\t\t\tweekday: \"short\",\n\t\t\t\t\t\tday: \"numeric\",\n\t\t\t\t\t\tmonth: \"short\",\n\t\t\t\t\t\thour: \"numeric\",\n\t\t\t\t\t\tminute: \"numeric\",\n\t\t\t\t\t} as const,\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t),\n\t\t\ttime: new Intl.DateTimeFormat(\n\t\t\t\ttag,\n\t\t\t\tObject.assign(\n\t\t\t\t\t{},\n\t\t\t\t\t{\n\t\t\t\t\t\thour: \"numeric\",\n\t\t\t\t\t\tminute: \"numeric\",\n\t\t\t\t\t} as const,\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t),\n\t\t\tdateTime: new Intl.DateTimeFormat(\n\t\t\t\ttag,\n\t\t\t\tObject.assign(\n\t\t\t\t\t{},\n\t\t\t\t\t{\n\t\t\t\t\t\tday: \"numeric\",\n\t\t\t\t\t\tmonth: \"short\",\n\t\t\t\t\t\tyear: \"numeric\",\n\t\t\t\t\t\thour: \"numeric\",\n\t\t\t\t\t\tminute: \"numeric\",\n\t\t\t\t\t} as const,\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t),\n\t\t\tdateTimeShort: new Intl.DateTimeFormat(\n\t\t\t\ttag,\n\t\t\t\tObject.assign(\n\t\t\t\t\t{},\n\t\t\t\t\t{\n\t\t\t\t\t\tday: \"numeric\",\n\t\t\t\t\t\tmonth: \"numeric\",\n\t\t\t\t\t\tyear: \"numeric\",\n\t\t\t\t\t\thour: \"numeric\",\n\t\t\t\t\t} as const,\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t),\n\t\t\tweekdayShort: new Intl.DateTimeFormat(tag, {\n\t\t\t\tweekday: \"short\",\n\t\t\t}),\n\t\t\tweekdayNarrow: new Intl.DateTimeFormat(tag, {\n\t\t\t\tweekday: \"narrow\",\n\t\t\t}),\n\t\t\tpriceWithCurrency: new Intl.NumberFormat(tag, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency: \"EUR\",\n\t\t\t\tminimumFractionDigits: 2,\n\t\t\t}),\n\t\t\tpriceWithCurrencyWithoutFractionDigits: new Intl.NumberFormat(tag, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency: \"EUR\",\n\t\t\t\tmaximumFractionDigits: 0,\n\t\t\t\tminimumFractionDigits: 0,\n\t\t\t}),\n\t\t\tpriceWithoutCurrency: new Intl.NumberFormat(tag, {\n\t\t\t\tstyle: \"decimal\",\n\t\t\t\tminimumFractionDigits: 2,\n\t\t\t}),\n\t\t\tpriceWithoutCurrencyWithoutFractionDigits: new Intl.NumberFormat(tag, {\n\t\t\t\tstyle: \"decimal\",\n\t\t\t\tmaximumFractionDigits: 0,\n\t\t\t\tminimumFractionDigits: 0,\n\t\t\t}),\n\t\t\tmonthLong: new Intl.DateTimeFormat(tag, {\n\t\t\t\tmonth: \"long\",\n\t\t\t}),\n\t\t\tmonthWithYear: new Intl.DateTimeFormat(tag, {\n\t\t\t\tmonth: \"long\",\n\t\t\t\tyear: \"2-digit\",\n\t\t\t}),\n\t\t\tmonthWithFullYear: new Intl.DateTimeFormat(tag, {\n\t\t\t\tmonth: \"long\",\n\t\t\t\tyear: \"numeric\",\n\t\t\t}),\n\t\t\tyearNumeric: new Intl.DateTimeFormat(tag, {\n\t\t\t\tyear: \"numeric\",\n\t\t\t}),\n\t\t}\n\t}\n\n\texists(id: TranslationKey): boolean {\n\t\ttry {\n\t\t\tthis.get(id)\n\t\t\treturn true\n\t\t} catch (e) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * @throws An error if there is no translation for the given id.\n\t */\n\tget(id: TranslationKey, replacements?: Record<string, string | number>): string {\n\t\tif (id == null) {\n\t\t\treturn \"\"\n\t\t}\n\n\t\tif (id === \"emptyString_msg\") {\n\t\t\treturn \"\\u2008\"\n\t\t}\n\n\t\tvar text = this.translations.keys[id]\n\n\t\tif (!text) {\n\t\t\t// try fallback language\n\t\t\ttext = this.fallback.keys[id]\n\n\t\t\tif (!text) {\n\t\t\t\t// try static definitions\n\t\t\t\ttext = this.staticTranslations[id]\n\n\t\t\t\tif (!text) {\n\t\t\t\t\tthrow new Error(\"no translation found for id \" + id)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let param in replacements) {\n\t\t\ttext = replaceAll(text, param, String(replacements[param]))\n\t\t}\n\n\t\treturn text\n\t}\n\n\tgetMaybeLazy(value: TranslationText): string {\n\t\treturn typeof value === \"function\" ? value() : lang.get(value)\n\t}\n}\n\n/**\n * Gets the default language derived from the browser language.\n * @param restrictions An array of language codes the selection should be restricted to\n */\nexport function getLanguageNoDefault(restrictions?: LanguageCode[]): { code: LanguageCode; languageTag: string } | null {\n\t// navigator.languages can be an empty array on android 5.x devices\n\tlet languageTags\n\n\tif (typeof navigator !== \"undefined\") {\n\t\tlanguageTags = navigator.languages && navigator.languages.length > 0 ? navigator.languages : [navigator.language]\n\t} else if (typeof process !== \"undefined\" && typeof process.env !== \"undefined\") {\n\t\tconst locale = process.env.LC_ALL || process.env.LC_MESSAGES || process.env.LANG || process.env.LANGUAGE || process.env.LC_NAME\n\n\t\tif (locale) {\n\t\t\tlanguageTags = [locale.split(\".\")[0].replace(\"_\", \"-\")]\n\t\t}\n\t}\n\n\tif (languageTags) {\n\t\tfor (let tag of languageTags) {\n\t\t\tlet code = getSubstitutedLanguageCode(tag, restrictions)\n\n\t\t\tif (code) {\n\t\t\t\treturn {\n\t\t\t\t\tcode: code,\n\t\t\t\t\tlanguageTag: tag,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null\n}\n\n/**\n * Gets the default language derived from the browser language.\n * @param restrictions An array of language codes the selection should be restricted to\n */\nexport function getLanguage(restrictions?: LanguageCode[]): {\n\tcode: LanguageCode\n\tlanguageTag: string\n} {\n\tconst language = getLanguageNoDefault(restrictions)\n\tif (language) return language\n\n\tif (restrictions == null || restrictions.indexOf(\"en\") !== -1) {\n\t\treturn {\n\t\t\tcode: \"en\",\n\t\t\tlanguageTag: \"en-US\",\n\t\t}\n\t} else {\n\t\treturn {\n\t\t\tcode: restrictions[0],\n\t\t\tlanguageTag: restrictions[0].replace(\"/_/g\", \"-\"),\n\t\t}\n\t}\n}\n\nexport function getSubstitutedLanguageCode(tag: string, restrictions?: LanguageCode[]): LanguageCode | null {\n\tlet code = tag.toLowerCase().replace(\"-\", \"_\")\n\tlet language = languages.find((l) => l.code === code && (restrictions == null || restrictions.indexOf(l.code) !== -1))\n\n\tif (language == null) {\n\t\tif (code === \"zh_hk\" || code === \"zh_tw\") {\n\t\t\tlanguage = languages.find((l) => l.code === \"zh_hant\")\n\t\t} else {\n\t\t\tlet basePart = getBasePart(code)\n\t\t\tlanguage = languages.find((l) => getBasePart(l.code) === basePart && (restrictions == null || restrictions.indexOf(l.code) !== -1))\n\t\t}\n\t}\n\n\tif (language) {\n\t\tlet customizations: WhitelabelCustomizations | null = null\n\n\t\t// accessing `window` throws an error on desktop, and this file is imported by DesktopMain\n\t\tif (typeof window !== \"undefined\") {\n\t\t\tcustomizations = getWhitelabelCustomizations(window)\n\t\t}\n\n\t\tconst germanCode = customizations?.germanLanguageCode\n\n\t\tif (language.code === \"de\" && germanCode != null) {\n\t\t\treturn downcast(germanCode)\n\t\t} else {\n\t\t\treturn language.code\n\t\t}\n\t} else {\n\t\treturn null\n\t}\n}\n\nfunction getBasePart(code: string): string {\n\tconst indexOfUnderscore = code.indexOf(\"_\")\n\n\tif (indexOfUnderscore > 0) {\n\t\treturn code.substring(0, indexOfUnderscore)\n\t} else {\n\t\treturn code\n\t}\n}\n\nexport function getAvailableLanguageCode(code: string): string {\n\treturn getSubstitutedLanguageCode(code) || \"en\"\n}\n\n/**\n * pt_br -> pt-BR\n * @param code\n */\nexport function languageCodeToTag(code: string): string {\n\tif (code === \"de_sie\") {\n\t\treturn \"de\"\n\t}\n\n\tconst indexOfUnderscore = code.indexOf(\"_\")\n\n\tif (indexOfUnderscore === -1) {\n\t\treturn code\n\t} else {\n\t\tconst [before, after] = code.split(\"_\")\n\t\treturn `${before}-${after.toUpperCase()}`\n\t}\n}\n\nexport const assertTranslation: (id: string) => TranslationKey = downcast\nexport type LanguageViewModelType = LanguageViewModel\nexport const lang: LanguageViewModel = new LanguageViewModel()\n","import { assertMainOrNodeBoot } from \"../../api/common/Env\"\n\nassertMainOrNodeBoot()\nexport type EasingFunction = (percent: number) => number\nconst EasingType = {\n\tlinear: 1,\n\tquad: 2,\n\tcubic: 3,\n\tquart: 4,\n\tquint: 5,\n}\n\n/*\n * Easings. Implemented as described in http://upshots.org/actionscript/jsas-understanding-easing\n * based on https://github.com/jquery/jquery-ui/blob/master/ui/effect.js#L1581\n *\n * @see: http://easings.net/\n * @see: http://robertpenner.com/easing/\n */\nexport const ease: Record<string, EasingFunction> = {\n\tin: function (percent: number): number {\n\t\treturn Math.pow(percent, EasingType.cubic) // cubic\n\t},\n\tout: function (percent: number): number {\n\t\treturn 1 - ease.in(1 - percent)\n\t},\n\tinOut: function (percent: number): number {\n\t\treturn percent < 0.5 ? ease.in(percent * 2) / 2 : 1 - ease.in(percent * -2 + 2) / 2\n\t},\n\tlinear: function (percent: number) {\n\t\treturn percent\n\t},\n}\n","import { assert } from \"@tutao/tutanota-utils\"\nimport { assertMainOrNodeBoot } from \"../../api/common/Env\"\n\nassertMainOrNodeBoot()\n// 3 or 6 digit hex color codes\nexport const VALID_HEX_CODE_FORMAT: RegExp = new RegExp(\"^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$\")\n\nexport function isColorLight(c: string): boolean {\n\tconst { r, g, b } = hexToRgb(c)\n\t// Counting the perceptive luminance\n\t// human eye favors green color...\n\tconst a = 1 - (0.299 * r + 0.587 * g + 0.114 * b) / 255\n\treturn a < 0.5\n}\n\nexport function hexToRgb(colorCode: string): {\n\tr: number\n\tg: number\n\tb: number\n} {\n\tassert(VALID_HEX_CODE_FORMAT.test(colorCode), \"Invalid color code: \" + colorCode)\n\tlet hexWithoutHash = colorCode.slice(1)\n\n\tif (hexWithoutHash.length === 3) {\n\t\thexWithoutHash = expandHexTriplet(hexWithoutHash) // convert from 3 to 6 digits by duplicating each digit\n\t}\n\n\tconst rgb = parseInt(hexWithoutHash, 16) // convert rrggbb to decimal\n\n\tconst r = (rgb >> 16) & 0xff // extract red\n\n\tconst g = (rgb >> 8) & 0xff // extract green\n\n\tconst b = (rgb >> 0) & 0xff // extract blue\n\n\treturn {\n\t\tr,\n\t\tg,\n\t\tb,\n\t}\n}\n\nexport function rgbToHex(color: { r: number; g: number; b: number }): string {\n\treturn \"#\" + ((1 << 24) + (color.r << 16) + (color.g << 8) + color.b).toString(16).slice(1)\n}\n\n/**\n * Convert RGB to RRGGBB\n */\nexport function expandHexTriplet(triplet: string): string {\n\tassert(triplet.length === 3, \"Provided invalid value for triplet: \" + triplet)\n\treturn Array.from(triplet).reduce((acc, cur) => `${acc}${cur}${cur}`, \"\")\n}\n","import type { Base64 } from \"@tutao/tutanota-utils\"\nimport { base64ToUint8Array, typedEntries, uint8ArrayToBase64 } from \"@tutao/tutanota-utils\"\nimport type { LanguageCode } from \"./LanguageViewModel\"\nimport type { ThemeId } from \"../gui/theme\"\nimport type { CredentialsStorage, PersistentCredentials } from \"./credentials/CredentialsProvider.js\"\nimport { ProgrammingError } from \"../api/common/error/ProgrammingError\"\nimport type { CredentialEncryptionMode } from \"./credentials/CredentialEncryptionMode\"\nimport { assertMainOrNodeBoot } from \"../api/common/Env\"\nimport { PersistedAssignmentData, UsageTestStorage } from \"./UsageTestModel\"\nimport { client } from \"./ClientDetector\"\nimport { NewsItemStorage } from \"./news/NewsModel.js\"\nimport { CalendarViewType } from \"../calendar/view/CalendarGuiUtils.js\"\n\nassertMainOrNodeBoot()\nexport const defaultThemeId: ThemeId = \"light\"\n\n/**\n * Definition of the config object that will be saved to local storage\n */\ninterface ConfigObject {\n\t_version: number\n\t_credentials: Map<Id, PersistentCredentials>\n\tscheduledAlarmModelVersionPerUser: Record<Id, number>\n\t_themeId: ThemeId\n\t_language: LanguageCode | null\n\t_defaultCalendarView: Record<Id, CalendarViewType | null>\n\t/** map from user id to a list of calendar grouproots*/\n\t_hiddenCalendars: Record<Id, Id[]>\n\t/** map from user id to a list of expanded folders (elementId)*/\n\texpandedMailFolders: Record<Id, Id[]>\n\t_signupToken: string\n\t_credentialEncryptionMode: CredentialEncryptionMode | null\n\t_encryptedCredentialsKey: Base64 | null\n\t/** list of acknowledged news item ids for this device */\n\tacknowledgedNewsItems: Id[]\n\t_testDeviceId: string | null\n\t_testAssignments: PersistedAssignmentData | null\n\tofflineTimeRangeDaysByUser: Record<Id, number>\n\tconversationViewShowOnlySelectedMail: boolean\n}\n\n/**\n * Device config for internal user auto login. Only one config per device is stored.\n */\nexport class DeviceConfig implements CredentialsStorage, UsageTestStorage, NewsItemStorage {\n\tpublic static Version = 3\n\tpublic static LocalStorageKey = \"tutanotaConfig\"\n\n\tprivate config!: ConfigObject\n\n\tconstructor(private readonly _version: number, private readonly localStorage: Storage | null) {\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tconst loadedConfig = this.loadConfigFromLocalStorage() ?? {}\n\n\t\tlet doSave = false\n\t\tif (loadedConfig._version != null && loadedConfig._version !== DeviceConfig.Version) {\n\t\t\tmigrateConfig(loadedConfig)\n\t\t\tdoSave = true\n\t\t}\n\n\t\tlet signupToken\n\t\tif (loadedConfig._signupToken) {\n\t\t\tsignupToken = loadedConfig._signupToken\n\t\t} else {\n\t\t\tlet bytes = new Uint8Array(6)\n\t\t\tlet crypto = window.crypto\n\t\t\tcrypto.getRandomValues(bytes)\n\t\t\tsignupToken = uint8ArrayToBase64(bytes)\n\t\t\tdoSave = true\n\t\t}\n\n\t\tthis.config = {\n\t\t\t_version: DeviceConfig.Version,\n\t\t\t_credentials: loadedConfig._credentials ? new Map(typedEntries(loadedConfig._credentials)) : new Map(),\n\t\t\t_credentialEncryptionMode: loadedConfig._credentialEncryptionMode ?? null,\n\t\t\t_encryptedCredentialsKey: loadedConfig._encryptedCredentialsKey ?? null,\n\t\t\tacknowledgedNewsItems: loadedConfig.acknowledgedNewsItems ?? [],\n\t\t\t_themeId: loadedConfig._themeId ?? defaultThemeId,\n\t\t\tscheduledAlarmModelVersionPerUser: loadedConfig.scheduledAlarmModelVersionPerUser ?? {},\n\t\t\t_language: loadedConfig._language ?? null,\n\t\t\t_defaultCalendarView: loadedConfig._defaultCalendarView ?? {},\n\t\t\t_hiddenCalendars: loadedConfig._hiddenCalendars ?? {},\n\t\t\texpandedMailFolders: loadedConfig.expandedMailFolders ?? {},\n\t\t\t_testDeviceId: loadedConfig._testDeviceId ?? null,\n\t\t\t_testAssignments: loadedConfig._testAssignments ?? null,\n\t\t\t_signupToken: signupToken,\n\t\t\tofflineTimeRangeDaysByUser: loadedConfig.offlineTimeRangeDaysByUser ?? {},\n\t\t\tconversationViewShowOnlySelectedMail: loadedConfig.conversationViewShowOnlySelectedMail ?? false,\n\t\t}\n\n\t\t// We need to write the config if there was a migration and if we generate the signup token and if.\n\t\t// We do not save the config if there was no config. The config is stored when some value changes.\n\t\tif (doSave) {\n\t\t\tthis.writeToStorage()\n\t\t}\n\t}\n\n\tprivate loadConfigFromLocalStorage(): any | null {\n\t\tif (this.localStorage == null) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst loadedConfigString = this.localStorage.getItem(DeviceConfig.LocalStorageKey)\n\t\tif (loadedConfigString == null) {\n\t\t\treturn null\n\t\t}\n\n\t\ttry {\n\t\t\treturn JSON.parse(loadedConfigString)\n\t\t} catch (e) {\n\t\t\tconsole.warn(\"Could not parse device config\")\n\t\t\treturn null\n\t\t}\n\t}\n\n\tstore(persistentCredentials: PersistentCredentials): void {\n\t\tconst existing = this.config._credentials.get(persistentCredentials.credentialInfo.userId)\n\n\t\tif (existing?.databaseKey) {\n\t\t\tpersistentCredentials.databaseKey = existing.databaseKey\n\t\t}\n\n\t\tthis.config._credentials.set(persistentCredentials.credentialInfo.userId, persistentCredentials)\n\n\t\tthis.writeToStorage()\n\t}\n\n\tloadByUserId(userId: Id): PersistentCredentials | null {\n\t\treturn this.config._credentials.get(userId) ?? null\n\t}\n\n\tloadAll(): Array<PersistentCredentials> {\n\t\treturn Array.from(this.config._credentials.values())\n\t}\n\n\tdeleteByUserId(userId: Id): void {\n\t\tthis.config._credentials.delete(userId)\n\n\t\tthis.writeToStorage()\n\t}\n\n\tgetSignupToken(): string {\n\t\treturn this.config._signupToken\n\t}\n\n\tgetScheduledAlarmsModelVersion(userId: Id): number | null {\n\t\treturn this.config.scheduledAlarmModelVersionPerUser[userId] ?? null\n\t}\n\n\tsetScheduledAlarmsModelVersion(userId: Id, version: number): void {\n\t\tthis.config.scheduledAlarmModelVersionPerUser[userId] = version\n\t\tthis.writeToStorage()\n\t}\n\n\tsetNoAlarmsScheduled() {\n\t\tthis.config.scheduledAlarmModelVersionPerUser = {}\n\t\tthis.writeToStorage()\n\t}\n\n\tgetLanguage(): LanguageCode | null {\n\t\treturn this.config._language\n\t}\n\n\tsetLanguage(language: LanguageCode | null) {\n\t\tthis.config._language = language\n\t\tthis.writeToStorage()\n\t}\n\n\tprivate writeToStorage() {\n\t\ttry {\n\t\t\tif (this.localStorage != null) {\n\t\t\t\tthis.localStorage.setItem(\n\t\t\t\t\tDeviceConfig.LocalStorageKey,\n\t\t\t\t\tJSON.stringify(this.config, (key, value) => {\n\t\t\t\t\t\tif (key === \"_credentials\") {\n\t\t\t\t\t\t\treturn Object.fromEntries(this.config._credentials.entries())\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn value\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t}\n\t\t} catch (e) {\n\t\t\t// may occur in Safari < 11 in incognito mode because it throws a QuotaExceededError\n\t\t\t// DOMException will occurr if all cookies are disabled\n\t\t\tconsole.log(\"could not store config\", e)\n\t\t}\n\t}\n\n\tgetTheme(): ThemeId {\n\t\treturn this.config._themeId\n\t}\n\n\tsetTheme(theme: ThemeId) {\n\t\tif (this.config._themeId !== theme) {\n\t\t\tthis.config._themeId = theme\n\n\t\t\tthis.writeToStorage()\n\t\t}\n\t}\n\n\tgetDefaultCalendarView(userId: Id): CalendarViewType | null {\n\t\treturn this.config._defaultCalendarView[userId]\n\t}\n\n\tsetDefaultCalendarView(userId: Id, defaultView: CalendarViewType) {\n\t\tif (this.config._defaultCalendarView[userId] !== defaultView) {\n\t\t\tthis.config._defaultCalendarView[userId] = defaultView\n\n\t\t\tthis.writeToStorage()\n\t\t}\n\t}\n\n\tgetHiddenCalendars(user: Id): Id[] {\n\t\treturn this.config._hiddenCalendars.hasOwnProperty(user) ? this.config._hiddenCalendars[user] : []\n\t}\n\n\tsetHiddenCalendars(user: Id, calendars: Id[]) {\n\t\tif (this.config._hiddenCalendars[user] !== calendars) {\n\t\t\tthis.config._hiddenCalendars[user] = calendars\n\n\t\t\tthis.writeToStorage()\n\t\t}\n\t}\n\n\tgetExpandedFolders(user: Id): Id[] {\n\t\treturn this.config.expandedMailFolders.hasOwnProperty(user) ? this.config.expandedMailFolders[user] : []\n\t}\n\n\tsetExpandedFolders(user: Id, folders: Id[]) {\n\t\tif (this.config.expandedMailFolders[user] !== folders) {\n\t\t\tthis.config.expandedMailFolders[user] = folders\n\n\t\t\tthis.writeToStorage()\n\t\t}\n\t}\n\n\thasAcknowledgedNewsItemForDevice(newsItemId: Id): boolean {\n\t\treturn this.config.acknowledgedNewsItems.includes(newsItemId)\n\t}\n\n\tacknowledgeNewsItemForDevice(newsItemId: Id) {\n\t\tif (!this.config.acknowledgedNewsItems.includes(newsItemId)) {\n\t\t\tthis.config.acknowledgedNewsItems.push(newsItemId)\n\t\t\tthis.writeToStorage()\n\t\t}\n\t}\n\n\tgetCredentialEncryptionMode(): CredentialEncryptionMode | null {\n\t\treturn this.config._credentialEncryptionMode\n\t}\n\n\tsetCredentialEncryptionMode(encryptionMode: CredentialEncryptionMode | null) {\n\t\tthis.config._credentialEncryptionMode = encryptionMode\n\n\t\tthis.writeToStorage()\n\t}\n\n\tgetCredentialsEncryptionKey(): Uint8Array | null {\n\t\treturn this.config._encryptedCredentialsKey ? base64ToUint8Array(this.config._encryptedCredentialsKey) : null\n\t}\n\n\tsetCredentialsEncryptionKey(value: Uint8Array | null) {\n\t\tif (value) {\n\t\t\tthis.config._encryptedCredentialsKey = uint8ArrayToBase64(value)\n\t\t} else {\n\t\t\tthis.config._encryptedCredentialsKey = null\n\t\t}\n\n\t\tthis.writeToStorage()\n\t}\n\n\tasync getTestDeviceId(): Promise<string | null> {\n\t\treturn this.config._testDeviceId\n\t}\n\n\tasync storeTestDeviceId(testDeviceId: string): Promise<void> {\n\t\tthis.config._testDeviceId = testDeviceId\n\t\tthis.writeToStorage()\n\t}\n\n\tasync getAssignments(): Promise<PersistedAssignmentData | null> {\n\t\treturn this.config._testAssignments\n\t}\n\n\tasync storeAssignments(persistedAssignmentData: PersistedAssignmentData): Promise<void> {\n\t\tthis.config._testAssignments = persistedAssignmentData\n\t\tthis.writeToStorage()\n\t}\n\n\tgetOfflineTimeRangeDays(userId: Id): number | null {\n\t\treturn this.config.offlineTimeRangeDaysByUser[userId]\n\t}\n\n\tsetOfflineTimeRangeDays(userId: Id, days: number) {\n\t\tthis.config.offlineTimeRangeDaysByUser[userId] = days\n\t\tthis.writeToStorage()\n\t}\n\n\tgetConversationViewShowOnlySelectedMail(): boolean {\n\t\treturn this.config.conversationViewShowOnlySelectedMail\n\t}\n\n\tsetConversationViewShowOnlySelectedMail(setting: boolean) {\n\t\tthis.config.conversationViewShowOnlySelectedMail = setting\n\t\tthis.writeToStorage()\n\t}\n}\n\nexport function migrateConfig(loadedConfig: any) {\n\tif (loadedConfig === DeviceConfig.Version) {\n\t\tthrow new ProgrammingError(\"Should not migrate credentials, current version\")\n\t}\n\n\tif (loadedConfig._version < 2) {\n\t\tloadedConfig._credentials = []\n\t}\n\n\tif (loadedConfig._version < 3) {\n\t\tmigrateConfigV2to3(loadedConfig)\n\t}\n}\n\n/**\n * Migrate from V2 of the config to V3\n *\n * Exported for testing\n */\nexport function migrateConfigV2to3(loadedConfig: any) {\n\tconst oldCredentialsArray = loadedConfig._credentials\n\tloadedConfig._credentials = {}\n\n\tfor (let credential of oldCredentialsArray) {\n\t\tlet login, type\n\t\tif (credential.mailAddress.includes(\"@\")) {\n\t\t\tlogin = credential.mailAddress\n\t\t\ttype = \"internal\"\n\t\t} else {\n\t\t\t// in version 2 external users had userId as their email address\n\t\t\t// We use encryption stub in this version\n\t\t\tlogin = credential.userId\n\t\t\ttype = \"external\"\n\t\t}\n\n\t\tloadedConfig._credentials[credential.userId] = {\n\t\t\tcredentialInfo: {\n\t\t\t\tlogin,\n\t\t\t\tuserId: credential.userId,\n\t\t\t\ttype,\n\t\t\t},\n\t\t\tencryptedPassword: credential.encryptedPassword,\n\t\t\taccessToken: credential.accessToken,\n\t\t}\n\t}\n}\n\nexport const deviceConfig: DeviceConfig = new DeviceConfig(DeviceConfig.Version, client.localStorage() ? localStorage : null)\n","import { assertMainOrNodeBoot } from \"../../api/common/Env\"\n\nassertMainOrNodeBoot()\n\nexport function getLogoSvg(highlightColor: string, textColor: string): string {\n\treturn (\n\t\t'<svg viewBox=\"0 0 1054.473 236.49\" preserveAspectRatio=\"xMinYMid\" xml:space=\"preserve\" xmlns=\"http://www.w3.org/2000/svg\">' +\n\t\t`<g style=\"fill:${textColor};fill-opacity:1\" transform=\"translate(-132.628 -222.799)\">\n\t\t\t<path d=\"M494.016 299.858H451.32v-8.082h94.178v8.082h-42.696v121.939h-8.785V299.858zM543.209 396.496v-66.943h8.434v65.889c0 14.057 6.15 20.908 20.206 20.908 12.827 0 23.544-6.676 34.965-17.57v-69.228h8.434v92.245h-8.434v-15.285c-10.191 9.662-22.139 17.219-35.668 17.219-19.152-.001-27.937-10.543-27.937-27.235zM652.319 401.24v-64.133h-16.165v-7.555h16.165v-33.56h8.434v33.56h24.071v7.555h-24.071v62.902c0 9.84 3.339 15.463 14.935 15.463 3.515 0 7.028-.352 9.664-1.23v7.906c-2.987.527-6.501.879-10.366.879-15.287 0-22.667-6.15-22.667-21.787zM703.27 400.537c0-17.57 14.935-30.749 63.43-38.831v-5.623c0-14.056-7.38-21.084-20.03-21.084-15.287 0-25.478 5.974-35.845 15.287l-4.919-5.271c11.421-10.542 23.192-17.395 40.938-17.395 19.152 0 28.289 10.894 28.289 27.937v43.399c0 11.246.703 18.097 2.636 22.841h-8.961c-1.23-3.865-2.108-8.434-2.108-13.705-11.245 9.664-23.545 15.287-37.426 15.287-16.868 0-26.004-8.785-26.004-22.842zm63.429-.703v-31.803c-44.98 7.907-54.996 18.976-54.996 31.978 0 10.367 6.853 15.99 18.273 15.99 13.706.001 26.18-5.974 36.723-16.165z\" />\n \t\t\t<path d=\"M803.951 421.797v-92.772h15.286v13.881c8.083-7.907 19.68-15.813 34.79-15.813 17.746 0 27.41 10.191 27.41 27.762v66.943h-15.111v-63.604c0-12.299-5.271-18.098-17.043-18.098-11.069 0-20.382 5.798-30.046 14.935v66.768h-15.286zM903.572 375.411c0-31.978 20.382-48.319 43.224-48.319 22.666 0 43.048 16.341 43.048 48.319 0 31.802-20.382 48.319-43.048 48.319s-43.224-16.517-43.224-48.319zm70.986 0c0-19.328-9.313-35.316-27.762-35.316-17.746 0-27.937 14.408-27.937 35.316 0 19.679 9.137 35.493 27.937 35.493 17.57 0 27.762-14.233 27.762-35.493zM1019.535 399.307V341.5h-16.165v-12.475h16.165v-33.032h15.11v33.032h24.072V341.5h-24.072v54.469c0 9.84 3.163 14.76 14.408 14.76 3.338 0 7.028-.527 9.488-1.23v12.475c-2.636.527-8.435 1.055-13.178 1.055-19.503-.002-25.828-7.556-25.828-23.722zM1075.057 399.834c0-18.801 15.988-32.154 62.023-38.655v-4.217c0-11.597-6.149-17.219-17.57-17.219-14.057 0-24.423 6.15-33.56 14.056l-7.907-9.488c10.718-9.839 24.599-17.219 43.048-17.219 22.139 0 30.924 11.597 30.924 30.924v40.939c0 11.246.703 18.097 2.636 22.841h-15.462c-1.229-3.865-2.108-7.555-2.108-12.826-10.366 9.664-21.963 14.232-35.844 14.232-15.99.001-26.18-8.432-26.18-23.368zm62.023-2.108v-26.004c-35.316 5.623-47.089 14.232-47.089 25.829 0 8.961 5.974 13.706 15.638 13.706 12.299-.001 22.842-5.097 31.451-13.531z\" />\n\t       </g>` +\n\t\t`<path style=\"fill:${highlightColor}\" d=\"M22.875 0C10.235 0 0 10.246 0 22.872v211.23c0 .801.046 1.608.123 2.388 8.5-3.167 17.524-6.629 27.054-10.436 66.336-26.48 120.569-48.994 120.618-74.415 0-.814-.056-1.636-.172-2.458-3.43-25.098-63.407-32.879-63.324-44.381.007-.611.18-1.25.548-1.889 7.205-12.619 35.743-12.015 46.253-12.907 10.519-.913 35.206-.724 36.399-8.244.035-.232.057-.463.057-.695.028-6.987-16.977-9.726-16.977-9.726s20.635 3.083 20.579 11.11c0 .393-.048.8-.158 1.214-2.222 8.624-20.379 10.246-32.386 10.835-11.356.569-28.648 1.861-28.707 7.408-.007.323.049.66.165 1.004 2.71 8.11 66.09 12.015 106.64 33.061 23.335 12.099 34.94 32.422 40.263 53.418V22.869c0-12.626-10.243-22.872-22.869-22.872H22.875z\"/>` +\n\t\t`</svg>`\n\t)\n}\n","/**\n * @file color/theme definitions for default themes.\n */\nimport { getLogoSvg } from \"./base/Logo\"\nimport type { Theme, ThemeId } from \"./theme\"\nimport { assertMainOrNodeBoot } from \"../api/common/Env\"\n\nassertMainOrNodeBoot()\n\n/**\n *      light theme background\n */\nconst light_white = \"#ffffff\"\nconst grey_lighter_4 = \"#f6f6f6\"\nconst grey_lighter_3 = \"#eaeaea\"\nconst grey_lighter_2 = \"#e1e1e1\"\nconst grey_lighter_1 = \"#d5d5d5\"\nconst grey_lighter_0 = \"#b8b8b8\"\nconst grey = \"#868686\"\nconst grey_darker_0 = \"#707070\"\nconst grey_darker_1 = \"#303030\"\nconst red = \"#840010\"\nconst blue = \"#005885\"\nexport const logo_text_dark_grey = \"#4a4a4a\"\n\n/**\n *      dark theme background\n *\n *      Assuming the background is black #000000 (rgb(0,0,0)) and text is white #000000 (rgb(255, 255, 255)) and recommended opacity of 87%\n *\t    we get (x1 being foreground, x2 being background, x3 being result)\n *\t\tx3 = x2 + (x1-x2)*a1 or x3 = 0 + (255 - 0) * 0.87 = 221\n *\t\trgb(221, 221, 221) = #DDDDDD\n *      https://stackoverflow.com/questions/12228548/finding-equivalent-color-with-opacity\n *\n */\nconst light_lighter_1 = \"#DDDDDD\"\nconst light_lighter_0 = \"#aeaeae\"\nconst light_grey = \"#999999\"\nconst dark_lighter_2 = \"#4e4e4e\"\nconst dark_lighter_1 = \"#363636\"\nconst dark_lighter_0 = \"#232323\"\nconst dark = \"#222222\"\nconst dark_darker_0 = \"#111111\"\nconst green = \"#00d2a7\"\nexport const logo_text_bright_grey = \"#c5c7c7\"\n\n// These are constants that have been chosen because they work across themes\n// This is even lighter than hover, for special cases like inactive search bar background\nexport const stateBgLike = \"rgba(139,139,139,0.18)\"\nexport const stateBgHover = \"rgba(139,139,139,0.22)\"\nexport const stateBgFocus = \"rgba(139,139,139,0.29)\"\nexport const stateBgActive = \"rgba(139,139,139,0.38)\"\n\ntype Themes = Record<ThemeId, Theme>\nexport const themes: Themes = {\n\tlight: Object.freeze({\n\t\tthemeId: \"light\",\n\t\tlogo: getLogoSvg(red, logo_text_dark_grey),\n\t\tbutton_bubble_bg: grey_lighter_3,\n\t\tbutton_bubble_fg: grey_darker_1,\n\t\tcontent_fg: grey_darker_1,\n\t\tcontent_button: grey_darker_0,\n\t\tcontent_button_selected: red,\n\t\tcontent_button_icon: light_white,\n\t\tcontent_button_icon_selected: light_white,\n\t\tcontent_accent: red,\n\t\tcontent_bg: light_white,\n\t\tcontent_border: grey_lighter_1,\n\t\tcontent_message_bg: grey_lighter_0,\n\t\theader_bg: light_white,\n\t\theader_box_shadow_bg: grey_lighter_1,\n\t\theader_button: grey_darker_0,\n\t\theader_button_selected: red,\n\t\tlist_bg: light_white,\n\t\tlist_alternate_bg: grey_lighter_4,\n\t\tlist_accent_fg: red,\n\t\tlist_message_bg: grey_lighter_0,\n\t\tlist_border: grey_lighter_2,\n\t\tmodal_bg: grey_darker_1,\n\t\televated_bg: light_white,\n\t\tnavigation_bg: grey_lighter_4,\n\t\tnavigation_border: grey_lighter_2,\n\t\tnavigation_button: grey_darker_0,\n\t\tnavigation_button_icon: light_white,\n\t\tnavigation_button_selected: red,\n\t\tnavigation_button_icon_selected: light_white,\n\t\tnavigation_menu_bg: grey_lighter_3,\n\t\tnavigation_menu_icon: grey,\n\t}),\n\tdark: Object.freeze({\n\t\tthemeId: \"dark\",\n\t\tlogo: getLogoSvg(green, logo_text_bright_grey),\n\t\tbutton_bubble_bg: dark_lighter_2,\n\t\tbutton_bubble_fg: light_lighter_1,\n\t\tcontent_fg: light_lighter_1,\n\t\tcontent_button: light_lighter_0,\n\t\tcontent_button_selected: green,\n\t\tcontent_button_icon_bg: dark_lighter_2,\n\t\tcontent_button_icon: light_lighter_1,\n\t\tcontent_button_icon_selected: dark_lighter_0,\n\t\tcontent_accent: green,\n\t\tcontent_bg: dark_darker_0,\n\t\tcontent_border: dark_lighter_1,\n\t\tcontent_message_bg: dark_lighter_2,\n\t\theader_bg: dark,\n\t\theader_box_shadow_bg: dark_darker_0,\n\t\theader_button: light_lighter_0,\n\t\theader_button_selected: green,\n\t\tlist_bg: dark_darker_0,\n\t\tlist_alternate_bg: dark_lighter_0,\n\t\tlist_accent_fg: green,\n\t\tlist_message_bg: dark_lighter_2,\n\t\tlist_border: dark_lighter_1,\n\t\tmodal_bg: dark_darker_0,\n\t\televated_bg: dark_lighter_0,\n\t\tnavigation_bg: dark_lighter_0,\n\t\tnavigation_border: dark_lighter_1,\n\t\tnavigation_button: light_lighter_0,\n\t\tnavigation_button_icon_bg: dark_lighter_2,\n\t\tnavigation_button_icon: light_lighter_1,\n\t\tnavigation_button_selected: green,\n\t\tnavigation_button_icon_selected: light_lighter_0,\n\t\tnavigation_menu_bg: dark_darker_0,\n\t\tnavigation_menu_icon: light_grey,\n\t}),\n\tblue: Object.freeze({\n\t\tthemeId: \"blue\",\n\t\tlogo: getLogoSvg(blue, logo_text_dark_grey),\n\t\tbutton_bubble_bg: grey_lighter_3,\n\t\tbutton_bubble_fg: grey_darker_1,\n\t\tcontent_fg: grey_darker_1,\n\t\tcontent_button: grey_darker_0,\n\t\tcontent_button_selected: blue,\n\t\tcontent_button_icon: light_white,\n\t\tcontent_button_icon_selected: light_white,\n\t\tcontent_accent: blue,\n\t\tcontent_bg: light_white,\n\t\tcontent_border: grey_lighter_1,\n\t\tcontent_message_bg: grey_lighter_0,\n\t\theader_bg: light_white,\n\t\theader_box_shadow_bg: grey_lighter_1,\n\t\theader_button: grey_darker_0,\n\t\theader_button_selected: blue,\n\t\tlist_bg: light_white,\n\t\tlist_alternate_bg: grey_lighter_4,\n\t\tlist_accent_fg: blue,\n\t\tlist_message_bg: grey_lighter_0,\n\t\tlist_border: grey_lighter_2,\n\t\tmodal_bg: grey_darker_1,\n\t\televated_bg: light_white,\n\t\tnavigation_bg: grey_lighter_4,\n\t\tnavigation_border: grey_lighter_2,\n\t\tnavigation_button: grey_darker_0,\n\t\tnavigation_button_icon: light_white,\n\t\tnavigation_button_selected: blue,\n\t\tnavigation_button_icon_selected: light_white,\n\t\tnavigation_menu_bg: grey_lighter_3,\n\t\tnavigation_menu_icon: grey,\n\t}),\n}\n","import { defaultThemeId, DeviceConfig } from \"../misc/DeviceConfig\"\nimport type { HtmlSanitizer } from \"../misc/HtmlSanitizer\"\nimport stream from \"mithril/stream\"\nimport Stream from \"mithril/stream\"\nimport { assertMainOrNodeBoot, isApp, isDesktop } from \"../api/common/Env\"\nimport { downcast, findAndRemove, LazyLoaded, mapAndFilterNull, typedValues } from \"@tutao/tutanota-utils\"\nimport m from \"mithril\"\nimport type { BaseThemeId, Theme, ThemeId } from \"./theme\"\nimport { logo_text_bright_grey, logo_text_dark_grey, themes } from \"./builtinThemes\"\nimport type { ThemeCustomizations } from \"../misc/WhitelabelCustomizations\"\nimport { getWhitelabelCustomizations } from \"../misc/WhitelabelCustomizations\"\nimport { getLogoSvg } from \"./base/Logo\"\nimport { ThemeFacade } from \"../native/common/generatedipc/ThemeFacade\"\n\nassertMainOrNodeBoot()\n\nexport class ThemeController {\n\t_theme: Theme\n\t_themeId: ThemeId\n\t// Subscribe to this to get theme change events. Cannot be used to update the theme\n\tthemeIdChangedStream: Stream<ThemeId>\n\tinitialized: Promise<any>\n\n\tconstructor(private readonly themeFacade: ThemeFacade, private readonly htmlSanitizer: () => Promise<HtmlSanitizer>) {\n\t\t// this will change soon\n\t\tthis._themeId = defaultThemeId\n\t\tthis._theme = this.getDefaultTheme()\n\t\tthis.themeIdChangedStream = stream(this.themeId)\n\t\t// We run them in parallel to initialize as soon as possible\n\t\tthis.initialized = Promise.all([this._initializeTheme(), this._updateBuiltinThemes()])\n\t}\n\n\tasync _initializeTheme() {\n\t\t// If being accessed from a custom domain, the definition of whitelabelCustomizations is added to index.js serverside upon request\n\t\t// see RootHandler::applyWhitelabelFileModifications.\n\t\tconst whitelabelCustomizations = getWhitelabelCustomizations(window)\n\n\t\tif (whitelabelCustomizations && whitelabelCustomizations.theme) {\n\t\t\t// no need to persist anything if we are on whitelabel domain\n\t\t\tawait this.updateCustomTheme(whitelabelCustomizations.theme, false)\n\t\t} else {\n\t\t\t// It is theme info passed from native to be applied as early as possible.\n\t\t\t// Important! Do not blindly apply location.search, someone could try to do prototype pollution.\n\t\t\t// We check environment and also filter out __proto__\n\t\t\t// mithril's parseQueryString does not follow standard exactly so we try to use the same thing we use on the native side\n\t\t\tconst themeJson = window.location.href ? new URL(window.location.href).searchParams.get(\"theme\") : null\n\n\t\t\tif ((isApp() || isDesktop()) && themeJson) {\n\t\t\t\tconst parsedTheme: ThemeCustomizations = this._parseCustomizations(themeJson)\n\n\t\t\t\t// We also don't need to save anything in this case\n\t\t\t\tawait this.updateCustomTheme(parsedTheme, false)\n\t\t\t} else {\n\t\t\t\tawait this.reloadTheme()\n\t\t\t}\n\t\t}\n\t}\n\n\t_parseCustomizations(stringTheme: string): ThemeCustomizations {\n\t\t// Filter out __proto__ to avoid prototype pollution. We use Object.assign() which is not susceptible to it but it doesn't hurt.\n\t\treturn JSON.parse(stringTheme, (k, v) => (k === \"__proto__\" ? undefined : v))\n\t}\n\n\tasync _updateBuiltinThemes() {\n\t\t// In case we change built-in themes we want to save new copy on the device.\n\t\tfor (const theme of typedValues(themes)) {\n\t\t\tawait this.updateSavedThemeDefinition(theme)\n\t\t}\n\t}\n\n\tasync reloadTheme() {\n\t\tconst themeId = await this.themeFacade.getSelectedTheme()\n\t\tif (!themeId) return\n\t\tawait this.setThemeId(themeId, false)\n\t}\n\n\tget themeId(): ThemeId {\n\t\treturn this._themeId\n\t}\n\n\tasync _getTheme(themeId: ThemeId): Promise<Theme> {\n\t\tif (themes[themeId]) {\n\t\t\t// Make a defensive copy so that original theme definition is not modified.\n\t\t\treturn Object.assign({}, themes[themeId])\n\t\t} else {\n\t\t\tconst loadedThemes = (await this.themeFacade.getThemes()) as ReadonlyArray<Theme>\n\t\t\tconst customTheme = loadedThemes.find((t) => t.themeId === themeId)\n\n\t\t\tif (customTheme) {\n\t\t\t\tawait this._sanitizeTheme(customTheme)\n\t\t\t\treturn customTheme\n\t\t\t} else {\n\t\t\t\treturn this.getDefaultTheme()\n\t\t\t}\n\t\t}\n\t}\n\n\tgetCurrentTheme(): Theme {\n\t\treturn Object.assign({}, this._theme)\n\t}\n\n\t/**\n\t * Set the theme, if permanent is true then the locally saved theme will be updated\n\t */\n\tasync setThemeId(newThemeId: ThemeId, permanent: boolean = true) {\n\t\tconst newTheme = await this._getTheme(newThemeId)\n\n\t\tthis._applyTrustedTheme(newTheme, newThemeId)\n\n\t\tif (permanent) {\n\t\t\tawait this.themeFacade.setSelectedTheme(newThemeId)\n\t\t}\n\t}\n\n\t_applyTrustedTheme(newTheme: Theme, newThemeId: ThemeId) {\n\t\tObject.keys(this._theme).forEach((key) => delete downcast(this._theme)[key])\n\t\t// Always overwrite light theme so that optional things are not kept when switching\n\t\tObject.assign(this._theme, this.getDefaultTheme(), newTheme)\n\t\tthis._themeId = newThemeId\n\t\tthis.themeIdChangedStream(newThemeId)\n\t\tm.redraw()\n\t}\n\n\t/**\n\t * Apply the custom theme, if permanent === true, then the new theme will be saved\n\t */\n\tasync updateCustomTheme(customizations: ThemeCustomizations, permanent: boolean = true): Promise<void> {\n\t\tconst updatedTheme = this.assembleTheme(customizations)\n\t\t// Set no logo until we sanitize it.\n\t\tconst filledWithoutLogo = Object.assign({}, updatedTheme, {\n\t\t\tlogo: \"\",\n\t\t})\n\n\t\tthis._applyTrustedTheme(filledWithoutLogo, filledWithoutLogo.themeId)\n\n\t\tawait this._sanitizeTheme(updatedTheme)\n\n\t\t// Now apply with the logo\n\t\tthis._applyTrustedTheme(updatedTheme, filledWithoutLogo.themeId)\n\n\t\tif (permanent) {\n\t\t\tawait this.updateSavedThemeDefinition(updatedTheme)\n\t\t\tawait this.themeFacade.setSelectedTheme(updatedTheme.themeId)\n\t\t}\n\t}\n\n\tasync _sanitizeTheme(theme: Theme) {\n\t\tif (theme.logo) {\n\t\t\tconst logo = theme.logo\n\t\t\tconst htmlSanitizer = await this.htmlSanitizer()\n\t\t\ttheme.logo = htmlSanitizer.sanitizeHTML(logo).html\n\t\t}\n\t}\n\n\t/**\n\t * Save theme to the storage.\n\t */\n\tasync updateSavedThemeDefinition(updatedTheme: Theme): Promise<Theme> {\n\t\tconst nonNullTheme = Object.assign({}, this.getDefaultTheme(), updatedTheme)\n\t\tawait this._sanitizeTheme(nonNullTheme)\n\t\tconst oldThemes = (await this.themeFacade.getThemes()) as Array<Theme>\n\t\tfindAndRemove(oldThemes, (t) => t.themeId === updatedTheme.themeId)\n\t\toldThemes.push(nonNullTheme)\n\t\tawait this.themeFacade.setThemes(oldThemes)\n\t\treturn nonNullTheme\n\t}\n\n\tgetDefaultTheme(): Theme {\n\t\treturn Object.assign({}, themes[defaultThemeId])\n\t}\n\n\tgetBaseTheme(baseId: BaseThemeId): Theme {\n\t\t// Make a defensive copy so that original theme definition is not modified.\n\t\treturn Object.assign({}, themes[baseId])\n\t}\n\n\tshouldAllowChangingTheme(): boolean {\n\t\treturn window.whitelabelCustomizations == null\n\t}\n\n\t/**\n\t * Assembles a new theme object from customizations.\n\t */\n\tassembleTheme(customizations: ThemeCustomizations): Theme {\n\t\tif (!customizations.base) {\n\t\t\treturn Object.assign({}, customizations as Theme)\n\t\t} else if (customizations.base && customizations.logo) {\n\t\t\treturn Object.assign({}, this.getBaseTheme(customizations.base), customizations)\n\t\t} else {\n\t\t\tconst themeWithoutLogo = Object.assign({}, this.getBaseTheme(customizations.base), customizations)\n\t\t\tconst coloredTutanotaLogo = getLogoSvg(\n\t\t\t\tthemeWithoutLogo.content_accent,\n\t\t\t\tcustomizations.base === \"light\" ? logo_text_dark_grey : logo_text_bright_grey,\n\t\t\t)\n\t\t\treturn { ...themeWithoutLogo, ...{ logo: coloredTutanotaLogo } }\n\t\t}\n\t}\n\n\tasync getCustomThemes(): Promise<Array<ThemeId>> {\n\t\treturn mapAndFilterNull(await this.themeFacade.getThemes(), (theme) => {\n\t\t\treturn !(theme.themeId in themes) ? theme.themeId : null\n\t\t})\n\t}\n\n\tasync removeCustomThemes() {\n\t\tawait this.themeFacade.setThemes([])\n\t\tawait this.setThemeId(defaultThemeId, true)\n\t}\n}\n\nexport class NativeThemeFacade implements ThemeFacade {\n\tprivate readonly themeFacade: LazyLoaded<ThemeFacade>\n\n\tconstructor() {\n\t\tthis.themeFacade = new LazyLoaded<ThemeFacade>(async () => {\n\t\t\tconst { locator } = await import(\"../api/main/MainLocator\")\n\t\t\t// Theme initialization happens concurrently with locator initialization,\n\t\t\t// so we have to wait or native may not yet be defined when we first get here.\n\t\t\t// It would be nice to move all the global theme handling onto the locator as\n\t\t\t// well so we can have more control over this\n\t\t\tawait locator.initialized\n\t\t\treturn locator.themeFacade\n\t\t})\n\t}\n\n\tasync getSelectedTheme(): Promise<ThemeId | null> {\n\t\tconst dispatcher = await this.themeFacade.getAsync()\n\t\treturn dispatcher.getSelectedTheme()\n\t}\n\n\tasync setSelectedTheme(theme: ThemeId): Promise<void> {\n\t\tconst dispatcher = await this.themeFacade.getAsync()\n\t\treturn dispatcher.setSelectedTheme(theme)\n\t}\n\n\tasync getThemes(): Promise<Array<Theme>> {\n\t\tconst dispatcher = await this.themeFacade.getAsync()\n\t\treturn (await dispatcher.getThemes()) as Theme[]\n\t}\n\n\tasync setThemes(themes: ReadonlyArray<Theme>): Promise<void> {\n\t\tconst dispatcher = await this.themeFacade.getAsync()\n\t\treturn dispatcher.setThemes(themes)\n\t}\n}\n\nexport class WebThemeFacade implements ThemeFacade {\n\treadonly _deviceConfig: DeviceConfig\n\n\tconstructor(deviceConfig: DeviceConfig) {\n\t\tthis._deviceConfig = deviceConfig\n\t}\n\n\tasync getSelectedTheme(): Promise<ThemeId | null> {\n\t\treturn this._deviceConfig.getTheme()\n\t}\n\n\tasync setSelectedTheme(theme: ThemeId): Promise<void> {\n\t\treturn this._deviceConfig.setTheme(theme)\n\t}\n\n\tasync getThemes(): Promise<Array<Theme>> {\n\t\t// no-op\n\t\treturn []\n\t}\n\n\tasync setThemes(themes: ReadonlyArray<Theme>) {\n\t\t// no-op\n\t}\n}\n","import { client } from \"./ClientDetector\"\nimport type { TranslationKey } from \"./LanguageViewModel\"\nimport { BrowserType } from \"./ClientConstants\"\nimport { Keys } from \"../api/common/TutanotaConstants\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { assertMainOrNodeBoot } from \"../api/common/Env\"\nimport { mod } from \"@tutao/tutanota-utils\"\nimport m from \"mithril\"\n\nassertMainOrNodeBoot()\nexport const TABBABLE = \"button, input, textarea, div[contenteditable='true'], [tabindex='0']\"\nexport type KeyPress = {\n\tkeyCode: number\n\tkey: string\n\tctrl: boolean\n\tshift: boolean\n}\nexport type Key = {\n\tcode: number\n\tname: string\n}\n\n/**\n * @return false, if the default action should be aborted\n */\nexport type keyHandler = (key: KeyPress) => boolean\n\nexport interface Shortcut {\n\tkey: Key\n\tctrl?: boolean\n\t// undefined == false\n\talt?: boolean\n\t// undefined == false\n\tshift?: boolean\n\t// undefined == false\n\tmeta?: boolean\n\t// undefined == false\n\tenabled?: lazy<boolean>\n\n\texec(key: KeyPress, e?: Event): boolean | void\n\n\t// must return true, if preventDefault should not be invoked\n\thelp: TranslationKey\n}\n\nexport function focusPrevious(dom: HTMLElement): boolean {\n\tlet tabbable = Array.from(dom.querySelectorAll(TABBABLE)).filter(\n\t\t(e) => (e as HTMLElement).style.display !== \"none\" && (e as HTMLElement).tabIndex !== -1,\n\t) as HTMLElement[] // also filter for tabIndex here to restrict tabbing to invisible inputs\n\n\tlet selected = tabbable.find((e) => document.activeElement === e)\n\n\tif (selected) {\n\t\t//work around for squire so tabulator actions are executed properly\n\t\t//squire makes a list which can be indented and manages this with tab and shift tab\n\t\tconst selection = window.getSelection()\n\n\t\tif (\n\t\t\tselection &&\n\t\t\tselection.focusNode &&\n\t\t\t(selection.focusNode.nodeName === \"LI\" || (selection.focusNode.parentNode && selection.focusNode.parentNode.nodeName === \"LI\"))\n\t\t) {\n\t\t\treturn true //dont change selection if selection is in list\n\t\t} else {\n\t\t\ttabbable[mod(tabbable.indexOf(selected) - 1, tabbable.length)].focus()\n\t\t\treturn false\n\t\t}\n\t} else if (tabbable.length > 0) {\n\t\ttabbable[tabbable.length - 1].focus()\n\t\treturn false\n\t}\n\n\treturn true\n}\n\nexport function focusNext(dom: HTMLElement): boolean {\n\tlet tabbable = Array.from(dom.querySelectorAll(TABBABLE)).filter(\n\t\t(e) => (e as HTMLElement).style.display !== \"none\" && (e as HTMLElement).tabIndex !== -1,\n\t) as HTMLElement[] // also filter for tabIndex here to restrict tabbing to invisible inputs\n\n\tlet selected = tabbable.find((e) => document.activeElement === e)\n\n\tif (selected) {\n\t\t//work around for squire so tabulator actions are executed properly\n\t\t//squire makes a list which can be indented and manages this with tab and shift tab\n\t\tconst selection = window.getSelection()\n\n\t\tif (\n\t\t\tselection &&\n\t\t\tselection.focusNode &&\n\t\t\t(selection.focusNode.nodeName === \"LI\" || (selection.focusNode.parentNode && selection.focusNode.parentNode.nodeName === \"LI\"))\n\t\t) {\n\t\t\treturn true //dont change selection\n\t\t} else {\n\t\t\ttabbable[mod(tabbable.indexOf(selected) + 1, tabbable.length)].focus()\n\t\t\treturn false\n\t\t}\n\t} else if (tabbable.length > 0) {\n\t\ttabbable[0].focus()\n\t\treturn false\n\t}\n\n\treturn true\n}\n\nfunction createKeyIdentifier(keycode: number, ctrl?: boolean, alt?: boolean, shift?: boolean, meta?: boolean): string {\n\treturn keycode + (ctrl ? \"C\" : \"\") + (alt ? \"A\" : \"\") + (shift ? \"S\" : \"\") + (meta ? \"M\" : \"\")\n}\n\n/**\n * KeyManager offers the API for (un)registration of all keyboard shortcuts and routes\n * key presses to the correct handler.\n *\n * Shortcuts that are registered by a modal always take precedence.\n */\n\nclass KeyManager {\n\t_keyToShortcut: Map<string, Shortcut>\n\t// override for _shortcuts: If a modal is visible, only modal-shortcuts should be active\n\t_keyToModalShortcut: Map<string, Shortcut>\n\t_desktopShortcuts: Shortcut[]\n\t_isHelpOpen: boolean = false\n\n\tconstructor() {\n\t\tconst helpShortcut: Shortcut = {\n\t\t\tkey: Keys.F1,\n\t\t\texec: () => this.openF1Help(),\n\t\t\thelp: \"showHelp_action\",\n\t\t}\n\t\tconst helpId = createKeyIdentifier(helpShortcut.key.code)\n\t\tthis._keyToShortcut = new Map([[helpId, helpShortcut]])\n\t\t// override for _shortcuts: If a modal is visible, only modal-shortcuts should be active\n\t\tthis._keyToModalShortcut = new Map([[helpId, helpShortcut]])\n\t\tthis._desktopShortcuts = []\n\t\tif (!window.document.addEventListener) return\n\t\twindow.document.addEventListener(\"keydown\", (e) => this._handleKeydown(e), false)\n\t}\n\n\t_handleKeydown(e: KeyboardEvent): void {\n\t\tlet keyCode = e.which\n\t\tlet keysToShortcuts = this._keyToModalShortcut.size > 1 ? this._keyToModalShortcut : this._keyToShortcut\n\t\tlet shortcut = keysToShortcuts.get(createKeyIdentifier(keyCode, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey))\n\n\t\tif (shortcut != null && (shortcut.enabled == null || shortcut.enabled())) {\n\t\t\tif (\n\t\t\t\tshortcut.exec({\n\t\t\t\t\tkeyCode,\n\t\t\t\t\tkey: e.key,\n\t\t\t\t\tctrl: e.ctrlKey,\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\talt: e.altKey,\n\t\t\t\t\tshift: e.shiftKey,\n\t\t\t\t\tmeta: e.metaKey,\n\t\t\t\t}) !== true\n\t\t\t) {\n\t\t\t\te.preventDefault()\n\t\t\t}\n\t\t}\n\t\tm.redraw()\n\t}\n\n\t/**\n\t * open a dialog listing all currently active shortcuts\n\t * @param forceBaseShortcuts set to true for the special case where the dialog is opened\n\t * from the support dropdown (which registers its own shortcuts as modal shortcuts)\n\t */\n\topenF1Help(forceBaseShortcuts: boolean = false): void {\n\t\tif (this._isHelpOpen) return\n\t\tthis._isHelpOpen = true\n\t\t// we decide which shortcuts to show right now.\n\t\t//\n\t\t// the help dialog will register its own shortcuts which would override the\n\t\t// standard shortcuts if we did this later\n\t\t//\n\t\t// we can't do this in the register/unregister method because the modal\n\t\t// unregisters the old dialog shortcuts and then registers the new ones\n\t\t// when the top dialog changes, leading to a situation where\n\t\t// modalshortcuts is empty.\n\t\tconst shortcutsToShow =\n\t\t\tthis._keyToModalShortcut.size > 1 && !forceBaseShortcuts\n\t\t\t\t? Array.from(this._keyToModalShortcut.values()) // copy values, they will change\n\t\t\t\t: [...this._keyToShortcut.values(), ...this._desktopShortcuts]\n\t\timport(\"../gui/dialogs/ShortcutDialog.js\").then(({ showShortcutDialog }) => showShortcutDialog(shortcutsToShow)).then(() => (this._isHelpOpen = false))\n\t}\n\n\tregisterShortcuts(shortcuts: ReadonlyArray<Shortcut>) {\n\t\tKeys.META.code = client.browser === BrowserType.FIREFOX ? 224 : 91\n\n\t\tthis._applyOperation(shortcuts, (id, s) => this._keyToShortcut.set(id, s))\n\t}\n\n\tunregisterShortcuts(shortcuts: ReadonlyArray<Shortcut>) {\n\t\tthis._applyOperation(shortcuts, (id, s) => this._keyToShortcut.delete(id))\n\t}\n\n\tregisterDesktopShortcuts(shortcuts: ReadonlyArray<Shortcut>) {\n\t\tthis._applyOperation(shortcuts, (id, s) => this._desktopShortcuts.push(s))\n\t}\n\n\tregisterModalShortcuts(shortcuts: Array<Shortcut>) {\n\t\tthis._applyOperation(shortcuts, (id, s) => {\n\t\t\tthis._keyToModalShortcut.set(id, s)\n\t\t})\n\t}\n\n\tunregisterModalShortcuts(shortcuts: Array<Shortcut>) {\n\t\tthis._applyOperation(shortcuts, (id, s) => {\n\t\t\tthis._keyToModalShortcut.delete(id)\n\t\t})\n\t}\n\n\t/**\n\t *\n\t * @param shortcuts list of shortcuts to operate on\n\t * @param operation operation to execute for every shortcut and its ID\n\t * @private\n\t */\n\t_applyOperation(shortcuts: ReadonlyArray<Shortcut>, operation: (id: string, s: Shortcut) => unknown) {\n\t\tshortcuts.forEach((s) => operation(createKeyIdentifier(s.key.code, s.ctrl, s.alt, s.shift, s.meta), s))\n\t}\n}\n\nexport function isKeyPressed(keyCode: number, ...keys: Array<Values<typeof Keys>>): boolean {\n\treturn keys.some((key) => key.code === keyCode)\n}\n\nexport const keyManager: KeyManager = new KeyManager()\n","import m, { Params } from \"mithril\"\nimport { assertMainOrNodeBoot, isApp, isElectronClient, isIOSApp, Mode } from \"../api/common/Env\"\nimport { lang } from \"./LanguageViewModel\"\nimport { client } from \"./ClientDetector\"\nimport type { Indexer } from \"../api/worker/search/Indexer\"\nimport { remove } from \"@tutao/tutanota-utils\"\nimport { WebsocketConnectivityModel } from \"./WebsocketConnectivityModel.js\"\nimport { LoginController } from \"../api/main/LoginController.js\"\n\nassertMainOrNodeBoot()\nexport type KeyboardSizeListener = (keyboardSize: number) => unknown\nexport type windowSizeListener = (width: number, height: number) => unknown\n\nexport class WindowFacade {\n\tprivate _windowSizeListeners: windowSizeListener[]\n\tresizeTimeout: (AnimationFrameID | null) | (TimeoutID | null)\n\twindowCloseConfirmation: boolean\n\tprivate _windowCloseListeners: Set<(e: Event) => unknown>\n\tprivate _historyStateEventListeners: Array<(e: Event) => boolean> = []\n\tprivate _indexerFacade: Indexer | null = null\n\t// following two properties are for the iOS\n\tprivate _keyboardSize: number = 0\n\tprivate _keyboardSizeListeners: KeyboardSizeListener[] = []\n\tprivate _ignoreNextPopstate: boolean = false\n\tprivate connectivityModel!: WebsocketConnectivityModel\n\tprivate logins: LoginController | null = null\n\n\tconstructor() {\n\t\tthis._windowSizeListeners = []\n\t\tthis.resizeTimeout = null\n\t\tthis.windowCloseConfirmation = false\n\t\tthis._windowCloseListeners = new Set()\n\t\t// load async to reduce size of boot bundle\n\t\timport(\"../api/main/MainLocator\").then(async ({ locator }) => {\n\t\t\t// We need to wait til the locator has finished initializing before we read from it\n\t\t\t// because it is happening concurrently\n\t\t\tawait locator.initialized\n\t\t\tthis._indexerFacade = locator.indexerFacade\n\t\t\tthis.connectivityModel = locator.connectivityModel\n\n\t\t\tif (env.mode === Mode.App || env.mode === Mode.Desktop || env.mode === Mode.Admin) {\n\t\t\t\tthis.addPageInBackgroundListener()\n\t\t\t}\n\t\t})\n\n\t\tconst onresize = () => {\n\t\t\t// see https://developer.mozilla.org/en-US/docs/Web/Events/resize\n\t\t\tif (!this.resizeTimeout) {\n\t\t\t\tconst cb = () => {\n\t\t\t\t\tthis.resizeTimeout = null\n\n\t\t\t\t\tthis._resize() // The actualResizeHandler will execute at a rate of 15fps\n\t\t\t\t}\n\n\t\t\t\t// On mobile devices there's usually no resize but when changing orientation it's to early to\n\t\t\t\t// measure the size in requestAnimationFrame (it's usually incorrect size at this point)\n\t\t\t\tthis.resizeTimeout = client.isMobileDevice() ? setTimeout(cb, 66) : requestAnimationFrame(cb)\n\t\t\t}\n\t\t}\n\t\twindow.onresize = onresize\n\t\t// specifially for iOS: rotation through the unsupported orientation (e.g, 90 degrees 3 times) will not trigger the resize and we wouldn't resize\n\t\t// some things so we react to both, it is throttled anyway\n\t\twindow.onorientationchange = onresize\n\t}\n\n\t/**\n\t * Add a window resize listener with a listenerId\n\t * @param listener Provides the new width and height of the window if the values change.\n\t */\n\taddResizeListener(listener: windowSizeListener) {\n\t\tthis._windowSizeListeners.push(listener)\n\t}\n\n\tremoveResizeListener(listener: windowSizeListener) {\n\t\tremove(this._windowSizeListeners, listener)\n\t}\n\n\taddWindowCloseListener(listener: () => unknown): (...args: Array<any>) => any {\n\t\tthis._windowCloseListeners.add(listener)\n\n\t\tthis._checkWindowClosing(this._windowCloseListeners.size > 0)\n\n\t\treturn () => {\n\t\t\tthis._windowCloseListeners.delete(listener)\n\n\t\t\tthis._checkWindowClosing(this._windowCloseListeners.size > 0)\n\t\t}\n\t}\n\n\t_notifyCloseListeners(e: Event) {\n\t\tthis._windowCloseListeners.forEach((f) => f(e))\n\t}\n\n\taddKeyboardSizeListener(listener: KeyboardSizeListener) {\n\t\tthis._keyboardSizeListeners.push(listener)\n\n\t\tlistener(this._keyboardSize)\n\t}\n\n\tremoveKeyboardSizeListener(listener: KeyboardSizeListener) {\n\t\tremove(this._keyboardSizeListeners, listener)\n\t}\n\n\topenLink(href: string) {\n\t\tif (env.mode === Mode.App) {\n\t\t\twindow.open(href, \"_system\")\n\t\t} else {\n\t\t\twindow.open(href, \"_blank\")\n\t\t}\n\t}\n\n\tinit(logins: LoginController) {\n\t\tthis.logins = logins\n\n\t\tif (window.addEventListener && !isApp()) {\n\t\t\twindow.addEventListener(\"beforeunload\", (e) => this._beforeUnload(e))\n\t\t\twindow.addEventListener(\"popstate\", (e) => this._popState(e))\n\t\t\twindow.addEventListener(\"unload\", (e) => this._onUnload())\n\t\t}\n\n\t\t// needed to help the MacOs desktop client to distinguish between Cmd+Arrow to navigate the history\n\t\t// and Cmd+Arrow to navigate a text editor\n\t\tif (env.mode === Mode.Desktop && client.isMacOS && window.addEventListener) {\n\t\t\twindow.addEventListener(\"keydown\", (e) => {\n\t\t\t\tif (!e.metaKey || e.key === \"Meta\") return\n\n\t\t\t\tconst target = e.target as HTMLElement | null\n\t\t\t\t// prevent history nav if the active element is an input / squire editor\n\t\t\t\tif (target?.tagName === \"INPUT\" || target?.contentEditable === \"true\") {\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t} else if (e.key === \"ArrowLeft\") {\n\t\t\t\t\twindow.history.back()\n\t\t\t\t} else if (e.key === \"ArrowRight\") {\n\t\t\t\t\twindow.history.forward()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\t// call the resize listeners once to make sure everyone\n\t\t// has the current window size once we're done initializing\n\t\tthis._resize()\n\t}\n\n\t_resize() {\n\t\ttry {\n\t\t\tfor (const listener of this._windowSizeListeners) {\n\t\t\t\tlistener(window.innerWidth, window.innerHeight)\n\t\t\t}\n\t\t} finally {\n\t\t\tm.redraw()\n\t\t}\n\t}\n\n\t_checkWindowClosing(enable: boolean) {\n\t\tthis.windowCloseConfirmation = enable\n\t}\n\n\t_beforeUnload(e: any): string | null {\n\t\t// BeforeUnloadEvent\n\t\tconsole.log(\"windowfacade._beforeUnload\")\n\n\t\tthis._notifyCloseListeners(e)\n\n\t\tif (this.windowCloseConfirmation) {\n\t\t\tlet m = lang.get(\"closeWindowConfirmation_msg\")\n\t\t\te.returnValue = m\n\t\t\treturn m\n\t\t} else {\n\t\t\tthis.logins?.logout(true)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * add a function to call when onpopstate event occurs\n\t * @param listener: return true if this popstate may go ahead\n\t * @returns {Function}\n\t */\n\taddHistoryEventListener(listener: (e: Event) => boolean): () => void {\n\t\tthis._historyStateEventListeners.push(listener)\n\n\t\treturn () => {\n\t\t\tconst index = this._historyStateEventListeners.indexOf(listener)\n\n\t\t\tif (index !== -1) {\n\t\t\t\tthis._historyStateEventListeners.splice(index, 1)\n\t\t\t}\n\t\t}\n\t}\n\n\tremoveHistoryEventListener(listener: (e: Event) => boolean): void {\n\t\tremove(this._historyStateEventListeners, listener)\n\t}\n\n\t/**\n\t * calls the last history event listener that was added\n\t * and reverts the state change if it returns false\n\t * TODO: this also fires for forward-events and when the user jumps around in the history\n\t * TODO: by long-clicking the back/forward buttons.\n\t * TODO: solving this requires extensive bookkeeping because the events are indistinguishable by default\n\t * @param e: popstate DOM event\n\t * @private\n\t */\n\t_popState(e: Event) {\n\t\tconst len = this._historyStateEventListeners.length\n\t\tif (len === 0) return\n\n\t\tif (this._ignoreNextPopstate) {\n\t\t\tthis._ignoreNextPopstate = false\n\t\t\treturn\n\t\t}\n\n\t\tif (!this._historyStateEventListeners[len - 1](e)) {\n\t\t\tthis._ignoreNextPopstate = true\n\t\t\t// go 1 page forward in the history\n\t\t\t// this reverts the state change (if the event was triggered by a back-button press)\n\t\t\thistory.go(1)\n\t\t}\n\t}\n\n\t_onUnload() {\n\t\tif (this.windowCloseConfirmation && this.logins) {\n\t\t\tthis.logins.logout(true)\n\t\t}\n\t}\n\n\taddOnlineListener(listener: () => void) {\n\t\twindow.addEventListener(\"online\", listener)\n\t}\n\n\taddOfflineListener(listener: () => void) {\n\t\twindow.addEventListener(\"offline\", listener)\n\t}\n\n\tasync reload(args: Params) {\n\t\tif (isApp() || isElectronClient()) {\n\t\t\tif (!args.hasOwnProperty(\"noAutoLogin\")) {\n\t\t\t\targs.noAutoLogin = true\n\t\t\t}\n\n\t\t\tconst { locator } = await import(\"../api/main/MainLocator\")\n\n\t\t\tconst stringifiedArgs: Record<string, string> = {}\n\t\t\tfor (const [k, v] of Object.entries(args)) {\n\t\t\t\tif (v != null) {\n\t\t\t\t\tstringifiedArgs[k] = String(v)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait locator.commonSystemFacade.reload(stringifiedArgs)\n\t\t} else {\n\t\t\twindow.location.reload()\n\t\t}\n\t}\n\n\taddPageInBackgroundListener() {\n\t\t// For Android it's handled manually from native because visibilitychange listener is not called after the\n\t\t// app was inactive for some time.\n\t\t// See NativeWrapperCommands.js\n\t\tif (isIOSApp()) {\n\t\t\tdocument.addEventListener(\"visibilitychange\", () => {\n\t\t\t\tconsole.log(\"Visibility change, hidden: \", document.hidden)\n\n\t\t\t\tthis._indexerFacade?.onVisibilityChanged(!document.hidden)\n\n\t\t\t\tif (!document.hidden) {\n\t\t\t\t\t// On iOS devices the WebSocket close event fires when the app comes back to foreground\n\t\t\t\t\t// so we try to reconnect with a delay to receive _close event first. Otherwise\n\t\t\t\t\t// we may try to reconnect while we think that we're still connected\n\t\t\t\t\t// (e.g. first reconnect and then receive close).\n\t\t\t\t\t// We used to handle it in the EventBus and reconnect immediately but isIosApp()\n\t\t\t\t\t// check does not work in the worker currently.\n\t\t\t\t\t// Doing this for all apps just to be sure.\n\t\t\t\t\tsetTimeout(() => this.connectivityModel?.tryReconnect(false, true), 100)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\tonKeyboardSizeChanged(size: number) {\n\t\tthis._keyboardSize = size\n\n\t\tfor (let listener of this._keyboardSizeListeners) {\n\t\t\tlistener(size)\n\t\t}\n\n\t\tif (size > 0) {\n\t\t\t// reset position fixed for the body to allow scrolling in dialogs on iOS\n\t\t\t// https://github.com/scottjehl/Device-Bugs/issues/14\n\t\t\tconst body = document.body as any\n\t\t\tbody.style.position = \"unset\"\n\t\t\tsetTimeout(() => {\n\t\t\t\tbody.style.position = \"fixed\"\n\t\t\t}, 200)\n\t\t}\n\t}\n}\n\nexport const windowFacade: WindowFacade = new WindowFacade()\n","import m, { Children, Component } from \"mithril\"\nimport { alpha, AlphaEnum, animations } from \"./../animation/Animations\"\nimport { theme } from \"../theme\"\nimport type { Shortcut } from \"../../misc/KeyManager\"\nimport { keyManager } from \"../../misc/KeyManager\"\nimport { windowFacade } from \"../../misc/WindowFacade\"\nimport { insideRect, remove } from \"@tutao/tutanota-utils\"\nimport { LayerType } from \"../../RootView\"\nimport { assertMainOrNodeBoot } from \"../../api/common/Env\"\n\nassertMainOrNodeBoot()\n\ntype ModalComponentWrapper = {\n\tkey: number\n\tcomponent: ModalComponent\n\tneedsBg: boolean\n}\n\nclass Modal implements Component {\n\tcomponents: Array<ModalComponentWrapper>\n\t_uniqueComponent: ModalComponent | null\n\tview: Component[\"view\"]\n\tvisible: boolean\n\tcurrentKey: number\n\tprivate _closingComponents: Array<ModalComponent>\n\tprivate readonly _historyEventListener = (e: Event) => this._popState(e)\n\n\tconstructor() {\n\t\tthis.currentKey = 0\n\t\tthis.components = []\n\t\tthis.visible = false\n\t\tthis._uniqueComponent = null\n\t\tthis._closingComponents = []\n\n\t\tthis.view = (): Children => {\n\t\t\treturn m(\n\t\t\t\t\"#modal.fill-absolute\",\n\t\t\t\t{\n\t\t\t\t\toncreate: (_) => {\n\t\t\t\t\t\t// const lastComponent = last(this.components)\n\t\t\t\t\t\t// if (lastComponent) {\n\t\t\t\t\t\t// \tlastComponent.component.backgroundClick(e)\n\t\t\t\t\t\t// }\n\t\t\t\t\t},\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\"z-index\": LayerType.Modal,\n\t\t\t\t\t\tdisplay: this.visible ? \"\" : \"none\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tthis.components.map((wrapper, i, array) => {\n\t\t\t\t\treturn m(\n\t\t\t\t\t\t\".fill-absolute\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkey: wrapper.key,\n\t\t\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\t\t\t// do not set visible=true already in display() because it leads to modal staying open in a second window in Chrome\n\t\t\t\t\t\t\t\t// because onbeforeremove is not called in that case to set visible=false. this is probably an optimization in Chrome to reduce\n\t\t\t\t\t\t\t\t// UI updates if the window is not visible. setting visible=true here is fine because this code is not even called then\n\t\t\t\t\t\t\t\tthis.visible = true\n\t\t\t\t\t\t\t\tm.redraw()\n\t\t\t\t\t\t\t\tif (wrapper.needsBg) this.addAnimation(vnode.dom as HTMLElement, true)\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonclick: (event: MouseEvent) => {\n\t\t\t\t\t\t\t\tconst element = event.currentTarget as HTMLElement\n\t\t\t\t\t\t\t\t// This layer div has a single child, the modal component\n\t\t\t\t\t\t\t\tconst child = element.firstElementChild\n\n\t\t\t\t\t\t\t\t// child shouldn't be null but maybe the user click fast idk\n\t\t\t\t\t\t\t\tif (child) {\n\t\t\t\t\t\t\t\t\tconst childRect = child.getBoundingClientRect()\n\n\t\t\t\t\t\t\t\t\tif (!insideRect(event, childRect)) {\n\t\t\t\t\t\t\t\t\t\twrapper.component.backgroundClick(event)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\tzIndex: LayerType.Modal + 1 + i,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonbeforeremove: (vnode) => {\n\t\t\t\t\t\t\t\tif (wrapper.needsBg) {\n\t\t\t\t\t\t\t\t\tthis._closingComponents.push(wrapper.component)\n\n\t\t\t\t\t\t\t\t\treturn Promise.all([\n\t\t\t\t\t\t\t\t\t\tthis.addAnimation(vnode.dom as HTMLElement, false).then(() => {\n\t\t\t\t\t\t\t\t\t\t\tremove(this._closingComponents, wrapper.component)\n\n\t\t\t\t\t\t\t\t\t\t\tif (this.components.length === 0 && this._closingComponents.length === 0) {\n\t\t\t\t\t\t\t\t\t\t\t\tthis.visible = false\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\twrapper.component.hideAnimation(),\n\t\t\t\t\t\t\t\t\t]).then(() => {\n\t\t\t\t\t\t\t\t\t\tm.redraw()\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tif (this.components.length === 0 && this._closingComponents.length === 0) {\n\t\t\t\t\t\t\t\t\t\tthis.visible = false\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn wrapper.component.hideAnimation().then(() => m.redraw())\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tm(wrapper.component),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t}\n\n\tdisplay(component: ModalComponent, needsBg: boolean = true) {\n\t\t// move the handler to the top of the handler stack\n\t\twindowFacade.removeHistoryEventListener(this._historyEventListener)\n\t\twindowFacade.addHistoryEventListener(this._historyEventListener)\n\t\tif (this.components.length > 0) {\n\t\t\tkeyManager.unregisterModalShortcuts(this.components[this.components.length - 1].component.shortcuts())\n\t\t}\n\n\t\tconst existingIndex = this.components.findIndex((shownComponent) => shownComponent.component === component)\n\n\t\tif (existingIndex !== -1) {\n\t\t\tconsole.warn(\"Attempting to display the same modal component multiple times!\")\n\t\t\tthis.components.splice(existingIndex, 1)\n\t\t}\n\n\t\tthis.components.push({\n\t\t\tkey: this.currentKey++,\n\t\t\tcomponent: component,\n\t\t\tneedsBg,\n\t\t})\n\t\tm.redraw()\n\t\tkeyManager.registerModalShortcuts(component.shortcuts())\n\t}\n\n\t/**\n\t * notify components that a history state was popped. The Component Stack is notified from the top and the first\n\t * Component to return false will stop underlying components from receiving the notification.\n\t * Components that return true are expected to remove themselves from the Modal stack, eg dropdowns.\n\t * @param e: the DOM Event\n\t * @private\n\t */\n\t_popState(e: Event): boolean {\n\t\tconsole.log(\"modal popstate\")\n\t\tconst len = this.components.length\n\n\t\tif (len === 0) {\n\t\t\tconsole.log(\"no modals to close\")\n\t\t\treturn true\n\t\t}\n\n\t\t// get the keys because we're going to modify the component stack during iteration\n\t\tconst keys = this.components.map((c) => c.key)\n\n\t\tfor (let i = len - 1; i >= 0; i--) {\n\t\t\tconst component = this._getComponentByKey(keys[i])\n\n\t\t\tif (!component) {\n\t\t\t\tconsole.log(\"component went AWOL, continuing\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (!component.popState(e)) {\n\t\t\t\tconsole.log(\"component handled popstate\")\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t}\n\n\t/**\n\t * used for modal components that should only be opened once\n\t * multiple calls will be ignored if the first component is still visible\n\t * @param component\n\t */\n\tdisplayUnique(component: ModalComponent, needsBg: boolean = true) {\n\t\tif (this._uniqueComponent) {\n\t\t\tconsole.log(\"tried to open unique component while another was open!\")\n\t\t\treturn\n\t\t}\n\n\t\tthis.display(component, needsBg)\n\t\tthis._uniqueComponent = component\n\t}\n\n\t_getComponentByKey(key: number): ModalComponent | null {\n\t\tconst entry = this.components.find((c) => c.key === key)\n\t\treturn entry?.component ?? null\n\t}\n\n\tremove(component: ModalComponent): void {\n\t\tconst componentIndex = this.components.findIndex((wrapper) => wrapper.component === component)\n\n\t\tif (componentIndex === -1) {\n\t\t\tconsole.log(\"can't remove non existing component from modal\")\n\t\t\treturn\n\t\t}\n\n\t\tconst componentIsTopmostComponent = componentIndex === this.components.length - 1\n\n\t\tif (componentIsTopmostComponent) {\n\t\t\tconsole.log(\"removed topmost modal component\")\n\t\t\tkeyManager.unregisterModalShortcuts(component.shortcuts())\n\t\t}\n\n\t\tthis.components.splice(componentIndex, 1)\n\n\t\tif (this._uniqueComponent === component) {\n\t\t\tthis._uniqueComponent = null\n\t\t}\n\n\t\tm.redraw()\n\n\t\tif (this.components.length > 0 && componentIsTopmostComponent) {\n\t\t\t// the removed component was the last component, so we can now register the shortcuts of the now last component\n\t\t\tkeyManager.registerModalShortcuts(this.components[this.components.length - 1].component.shortcuts())\n\t\t}\n\t}\n\n\t/**\n\t * adds an animation to the topmost component\n\t */\n\taddAnimation(domLayer: HTMLElement, fadein: boolean): Promise<unknown> {\n\t\tconst start = 0\n\t\tconst end = 0.5\n\t\treturn animations.add(domLayer, alpha(AlphaEnum.BackgroundColor, theme.modal_bg, fadein ? start : end, fadein ? end : start))\n\t}\n}\n\nexport const modal: Modal = new Modal()\n\nexport interface ModalComponent extends Component {\n\thideAnimation(): Promise<void>\n\n\tonClose(): void\n\n\tshortcuts(): Shortcut[]\n\n\tbackgroundClick(e: MouseEvent): void\n\n\t/**\n\t * will be called by the main modal if no other component above this one blocked the event (previous components returned true)\n\t * return false if the event was handled and lower components shouldn't be notified, true otherwise\n\t * @param e\n\t */\n\tpopState(e: Event): boolean\n}\n","import { assertMainOrNodeBoot } from \"../api/common/Env\"\n\nassertMainOrNodeBoot()\ntype LogCategory = Record<string, string>\nexport const Cat: Record<string, LogCategory> = {\n\tcss: {\n\t\tname: \"css\",\n\t\tcolor: \"orange\",\n\t},\n\tmithril: {\n\t\tname: \"mithril\",\n\t\tcolor: \"darkgreen\",\n\t},\n\terror: {\n\t\tname: \"error\",\n\t\tcolor: \"red\",\n\t},\n\tinfo: {\n\t\tname: \"info\",\n\t\tcolor: \"lightblue\",\n\t},\n\tdebug: {\n\t\tname: \"debug\",\n\t\tcolor: \"#009688\",\n\t},\n}\nconst activeCategories: LogCategory[] = []\n\nexport function enable(cat: LogCategory) {\n\tactiveCategories.push(cat)\n}\n\nexport function log(category: LogCategory, message: string, ...args: any[]) {\n\tif (activeCategories.indexOf(category) === -1) return\n\tconsole.log(\"%c\" + category.name, \"color:\" + category.color, message, ...args)\n}\n\nexport function timer(category: LogCategory): (...args: Array<any>) => any {\n\tif (activeCategories.indexOf(category) === -1) {\n\t\treturn function () {}\n\t}\n\n\tlet start = window.performance.now()\n\treturn function () {\n\t\treturn Math.round(window.performance.now() - start)\n\t}\n}\n","import { assertMainOrNodeBoot } from \"../api/common/Env\"\n\nassertMainOrNodeBoot()\nexport const size = {\n\ticon_size_xl: 32,\n\ticon_size_large: 24,\n\ticon_size_medium: 16,\n\ticon_message_box: 80,\n\thpad_small: 5,\n\thpad: 10,\n\thpad_medium: 20,\n\thpad_large: 20,\n\thpad_large_mobile: 6,\n\thpad_button: 6,\n\thpad_nav_button: 9,\n\t// 6 + 9 = 15px\n\tvpad_xs: 3,\n\tvpad: 16,\n\tvpad_small: 8,\n\tvpad_ml: 25,\n\tvpad_large: 32,\n\tvpad_xl: 48,\n\ttext_bubble_tpad: 20,\n\tborder_radius_small: 3,\n\tborder_radius: 6,\n\tborder_radius_big: 9,\n\tborder_selection: 4,\n\tfont_size_base: 16,\n\tfont_size_smaller: 14,\n\tfont_size_small: 12,\n\tbutton_height: 44,\n\tbutton_height_accent: 40,\n\tbutton_height_bubble: 30,\n\tbutton_height_compact: 30,\n\tbutton_icon_bg_size: 32,\n\tbutton_floating_size: 56,\n\n\tnavbar_height: 70,\n\tnavbar_height_mobile: 52,\n\tbottom_nav_bar: 50,\n\tnavbar_button_width: 80,\n\tnavbar_edge_width_mobile: 58,\n\theader_logo_height: 38,\n\theader_logo_height_mobile: 32,\n\tlist_row_height: 68,\n\tcolumn_width_s_desktop: 135,\n\tcolumn_width_s_mobile: 70,\n\tline_height: 1.428571429,\n\t// 20/14,\n\tline_height_m: 1.6,\n\tline_height_l: 1.8,\n\n\tget calendar_line_height(): number {\n\t\treturn this.font_size_small + 6\n\t},\n\n\tget calendar_hour_height(): number {\n\t\treturn (this.calendar_line_height + 2 * this.calendar_event_border + this.calendar_day_event_padding) * 4\n\t},\n\n\tcalendar_hour_width: 80,\n\tcalendar_hour_width_mobile: 60,\n\tcalendar_event_margin: 6,\n\tcalendar_event_margin_mobile: 2,\n\tcalendar_event_border: 1,\n\tcalendar_day_event_padding: 2,\n\tdrawer_menu_width: 44,\n\tfirst_col_min_width: 240,\n\tfirst_col_max_width: 300,\n\tsecond_col_min_width: 300,\n\tsecond_col_max_width: 350,\n\tthird_col_min_width: 600,\n\tthird_col_max_width: 2400,\n\n\tget desktop_layout_width(): number {\n\t\treturn this.first_col_min_width + this.second_col_min_width + this.third_col_min_width\n\t},\n\n\tget two_column_layout_width(): number {\n\t\treturn this.second_col_min_width + this.third_col_min_width\n\t},\n\n\tdot_size: 7,\n\tcheckbox_size: 14,\n}\nexport const inputLineHeight: number = size.font_size_base + 8\n\nexport function px(value: number): string {\n\treturn value + \"px\"\n}\n","import { Cat, log, timer } from \"../misc/Log\"\nimport { size } from \"./size\"\nimport { assertMainOrNodeBoot, isAdminClient, isTest } from \"../api/common/Env\"\nimport { windowFacade } from \"../misc/WindowFacade\"\nimport { theme, themeController } from \"./theme\"\nimport { assertNotNull, neverNull } from \"@tutao/tutanota-utils\"\nimport { client } from \"../misc/ClientDetector\"\n\nassertMainOrNodeBoot()\n\nexport type StyleSheetId = \"main\" | \"outline\"\n\n/**\n * Writes all styles to a single dom <style>-tag\n */\n\nclass Styles {\n\tstyles: Map<StyleSheetId, (...args: Array<any>) => any>\n\tinitialized: boolean\n\tbodyWidth: number\n\tbodyHeight: number\n\n\tprivate styleSheets = new Map<StyleSheetId, HTMLStyleElement>()\n\n\tconstructor() {\n\t\tthis.initialized = false\n\t\tthis.styles = new Map()\n\t\tthis.bodyWidth = neverNull(document.body).offsetWidth\n\t\tthis.bodyHeight = neverNull(document.body).offsetHeight\n\t\twindowFacade.addResizeListener((width: number, height: number) => {\n\t\t\tthis.bodyWidth = width\n\t\t\tthis.bodyHeight = height\n\t\t})\n\t\tthemeController.themeIdChangedStream.map(() => {\n\t\t\tthis.updateDomStyles()\n\t\t})\n\t}\n\n\tinit() {\n\t\tif (this.initialized) return\n\t\tthis.initialized = true\n\n\t\tthis.updateDomStyles()\n\t}\n\n\tgetStyleSheetElement(id: StyleSheetId): Node {\n\t\treturn assertNotNull(this.styleSheets.get(id)).cloneNode(true)\n\t}\n\n\tisDesktopLayout(): boolean {\n\t\treturn this.bodyWidth >= size.desktop_layout_width\n\t}\n\n\tisSingleColumnLayout(): boolean {\n\t\treturn this.bodyWidth < size.two_column_layout_width\n\t}\n\n\tisUsingBottomNavigation(): boolean {\n\t\treturn !isAdminClient() && (client.isMobileDevice() || !this.isDesktopLayout())\n\t}\n\n\tregisterStyle(id: StyleSheetId, styleCreator: (...args: Array<any>) => any) {\n\t\tif (!this.initialized && this.styles.has(id)) {\n\t\t\tthrow new Error(\"duplicate style definition: \" + id)\n\t\t}\n\n\t\tthis.styles.set(id, styleCreator)\n\n\t\tif (this.initialized) {\n\t\t\tlog(Cat.css, \"update style\", id, styleCreator(theme))\n\n\t\t\tthis.updateDomStyle(id, styleCreator)\n\t\t}\n\t}\n\n\tupdateStyle(id: StyleSheetId) {\n\t\tif (!this.initialized || !this.styles.has(id)) {\n\t\t\tthrow new Error(\"cannot update nonexistent style \" + id)\n\t\t}\n\n\t\tconst creator = neverNull(this.styles.get(id))\n\t\tlog(Cat.css, \"update style\", id, creator(theme))\n\n\t\tthis.updateDomStyle(id, creator)\n\t}\n\n\tprivate updateDomStyles() {\n\t\t// This is hacking but we currently import gui stuff from a lot of tested things\n\t\tif (isTest()) {\n\t\t\treturn\n\t\t}\n\n\t\tlet time = timer(Cat.css)\n\t\tArray.from(this.styles.entries()).map((entry) => {\n\t\t\tthis.updateDomStyle(entry[0], entry[1])\n\t\t})\n\t\tlog(Cat.css, \"creation time\", time())\n\t}\n\n\tprivate updateDomStyle(id: StyleSheetId, styleCreator: (...args: Array<any>) => any) {\n\t\tconst styleSheet = this.getDomStyleSheet(`css-${id}`)\n\t\tstyleSheet.textContent = toCss(styleCreator())\n\t\tthis.styleSheets.set(id, styleSheet)\n\t}\n\n\tprivate getDomStyleSheet(id: string): HTMLStyleElement {\n\t\tlet styleDomElement = document.getElementById(id)\n\n\t\tif (!styleDomElement) {\n\t\t\tstyleDomElement = document.createElement(\"style\")\n\t\t\tstyleDomElement.setAttribute(\"type\", \"text/css\")\n\t\t\tstyleDomElement.id = id\n\t\t\tstyleDomElement = document.getElementsByTagName(\"head\")[0].appendChild(styleDomElement)\n\t\t}\n\n\t\treturn styleDomElement as HTMLStyleElement\n\t}\n}\n\nfunction objectToCss(indent: string, key: string, o: Record<string, string>) {\n\tlet cssString = `${indent}${key} { \\n`\n\tcssString += indent + toCss(o, indent + \"  \")\n\tcssString += ` \\n${indent}} \\n`\n\treturn cssString\n}\n\nfunction toCss(obj: Record<string, any>, indent = \"\") {\n\tlet ret = Object.keys(obj)\n\t\t.map((key) => {\n\t\t\tif (obj[key] instanceof Array) {\n\t\t\t\treturn obj[key]\n\t\t\t\t\t.map((o: any) => {\n\t\t\t\t\t\treturn objectToCss(indent, key, o)\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t} else if (obj[key] instanceof Object) {\n\t\t\t\treturn objectToCss(indent, key, obj[key])\n\t\t\t} else {\n\t\t\t\treturn `${indent}${key}: ${obj[key]};`\n\t\t\t}\n\t\t})\n\t\t.join(\"\\n\")\n\treturn ret\n}\n\nexport const styles: Styles = new Styles()\n","import m, { Children, ClassComponent, Vnode } from \"mithril\"\nimport { modal } from \"./gui/base/Modal\"\nimport { overlay } from \"./gui/base/Overlay\"\nimport { styles } from \"./gui/styles\"\nimport { assertMainOrNodeBoot, isApp } from \"./api/common/Env\"\nimport { Keys } from \"./api/common/TutanotaConstants.js\"\nimport { isKeyPressed } from \"./misc/KeyManager.js\"\n\nassertMainOrNodeBoot()\n\nexport const enum LayerType {\n\t// Minimized editors, SearchBarOverlay\n\tView = 0,\n\t// notifications that require no user interaction\n\tLowPriorityOverlay = 100,\n\t// Foreground menu in mobile layout\n\tLowPriorityNotification = 150,\n\t// Editors, Dialogs\n\tForegroundMenu = 200,\n\t// Error message dialogs, Notifications\n\tModal = 300,\n\tOverlay = 400,\n}\n\nconst enum PrimaryNavigationType {\n\tKeyboard,\n\tTouch,\n\tMouse,\n\t// theoretically pen is also an option\n}\n\n// global, in case we have multiple instances for some reason\n/** What we infer to be the user's preferred navigation type. */\nlet currentNavigationType: PrimaryNavigationType = isApp() ? PrimaryNavigationType.Touch : PrimaryNavigationType.Mouse\n\n/**\n * View which wraps anything that we render.\n * It has overlay, modal and the main layers. It also defines some global handlers for better visual indication depending on the interaction.\n */\nexport class RootView implements ClassComponent {\n\tprivate dom: HTMLElement | null = null\n\tconstructor() {\n\t\t// still \"old-style\" component, we don't want to lose \"this\" reference\n\t\tthis.view = this.view.bind(this)\n\t}\n\n\tview(vnode: Vnode): Children {\n\t\treturn m(\n\t\t\t\"#root\" + (styles.isUsingBottomNavigation() ? \".mobile\" : \"\"),\n\t\t\t{\n\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\tthis.dom = vnode.dom as HTMLElement\n\t\t\t\t},\n\t\t\t\t// use pointer events instead of mousedown/touchdown because mouse events are still fired for touch on mobile\n\t\t\t\tonpointerup: (e: EventRedraw<PointerEvent>) => {\n\t\t\t\t\tif (e.pointerType === \"mouse\") {\n\t\t\t\t\t\tthis.switchNavType(PrimaryNavigationType.Mouse)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// can be \"touch\" or \"pen\", treat them the same for now\n\t\t\t\t\t\tthis.switchNavType(PrimaryNavigationType.Touch)\n\t\t\t\t\t}\n\t\t\t\t\te.redraw = false\n\t\t\t\t},\n\t\t\t\tonkeyup: (e: EventRedraw<KeyboardEvent>) => {\n\t\t\t\t\t// tab key can be pressed in some other situations e.g. editor but it would be switched back quickly again if needed.\n\t\t\t\t\tif (isKeyPressed(e.keyCode, Keys.TAB)) {\n\t\t\t\t\t\tthis.switchNavType(PrimaryNavigationType.Keyboard)\n\t\t\t\t\t}\n\t\t\t\t\te.redraw = false\n\t\t\t\t},\n\t\t\t\t// See styles for usages of these classes.\n\t\t\t\t// We basically use them in css combinators as a query for when to show certain interaction indicators.\n\t\t\t\tclass: this.classForType(),\n\t\t\t\tstyle: {\n\t\t\t\t\theight: \"100%\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t[m(overlay), m(modal), vnode.children],\n\t\t)\n\t}\n\n\tprivate switchNavType(newType: PrimaryNavigationType) {\n\t\tif (currentNavigationType === newType) {\n\t\t\treturn\n\t\t}\n\t\tthis.dom?.classList.remove(this.classForType())\n\t\tcurrentNavigationType = newType\n\t\tthis.dom?.classList.add(this.classForType())\n\t}\n\n\tprivate classForType() {\n\t\tswitch (currentNavigationType) {\n\t\t\tcase PrimaryNavigationType.Keyboard:\n\t\t\t\treturn \"keyboard-nav\"\n\t\t\tcase PrimaryNavigationType.Mouse:\n\t\t\t\treturn \"mouse-nav\"\n\t\t\tcase PrimaryNavigationType.Touch:\n\t\t\t\treturn \"touch-nav\"\n\t\t}\n\t}\n}\n\nexport const root: RootView = new RootView()\n","/**\n * @file Handler for all the uncaught errors.\n * ErrorHandler is decoupled from ErrorHandlerImpl to reduce boot bundle size.\n */\nimport { assertMainOrNodeBoot, isTest } from \"../api/common/Env\"\nimport { delay } from \"@tutao/tutanota-utils\"\n\nassertMainOrNodeBoot()\n\n/** Produced async function which will not try to run more often than @param ms. Does not cache the result. */\nfunction produceThrottledFunction<R>(ms: number, fn: () => Promise<R>): () => Promise<R> {\n\tlet lastTry = 0\n\treturn async () => {\n\t\tconst previousTry = lastTry\n\t\tlastTry = Date.now()\n\t\tconst sincePreviousTry = Date.now() - previousTry\n\n\t\t// |---|----|--------------|-----|\n\t\t//   1001  1003           1011\n\t\t//    a     b              c\n\t\t// ms: 10\n\t\t// a: previousTry\n\t\t// b: Date.now()\n\t\t// c: previousTry + ms\n\t\t// If the last call was at 1001 and we are now calling fn again at 1003 then we want to wait until 1011 which would be (a + ms) - b.\n\n\t\tif (previousTry !== 0 && sincePreviousTry < ms) {\n\t\t\tconst waitShouldEndAt = previousTry + ms\n\t\t\tconst timeUntilWaitEnd = waitShouldEndAt - Date.now()\n\t\t\tawait delay(timeUntilWaitEnd)\n\t\t}\n\n\t\treturn fn()\n\t}\n}\n\n/**\n * Throttled error handler. We have issues with error loops when reloading the page in Firefox and this gives browser a break of event\n * loop to be able to reload the page properly.\n * */\nconst importErrorHandler = produceThrottledFunction(200, () => import(\"./ErrorHandlerImpl.js\"))\n\nexport async function handleUncaughtError(e: Error) {\n\tif (isTest()) {\n\t\tthrow e\n\t}\n\n\ttry {\n\t\tconsole.log(\"error\", e, e.stack)\n\t\tconst { handleUncaughtErrorImpl } = await importErrorHandler()\n\t\tawait handleUncaughtErrorImpl(e)\n\t} catch (e) {\n\t\tconsole.error(\"Encountered error when trying to handle errors with ErrorHandlerImpl\", e)\n\t}\n}\n\nexport async function disableErrorHandlingDuringLogout() {\n\ttry {\n\t\tconst { disableErrorHandlingDuringLogout } = await importErrorHandler()\n\t\tdisableErrorHandlingDuringLogout()\n\t} catch (e) {\n\t\tconsole.error(\"Could not import ErrorHandlerImpl\", e)\n\t}\n}\n","import { assertMainOrNodeBoot, isApp, isDesktop, isTutanotaDomain } from \"../api/common/Env\"\nimport { lang } from \"../misc/LanguageViewModel\"\nimport { windowFacade } from \"../misc/WindowFacade\"\nimport m, { Component } from \"mithril\"\nimport { handleUncaughtError } from \"../misc/ErrorHandler\"\nimport { isNotSupportedError, isSecurityError, objToError } from \"../api/common/utils/Utils\"\n\nassertMainOrNodeBoot()\n\nfunction showUpdateOverlay(onUpdate: () => void) {\n\tconst notificationMessage: Component = {\n\t\tview: () => {\n\t\t\treturn m(\"span\", [\n\t\t\t\tlang.get(\"updateFound_label\"),\n\t\t\t\t\" \",\n\t\t\t\tisTutanotaDomain(location.hostname)\n\t\t\t\t\t? m(\n\t\t\t\t\t\t\t\"a\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\thref: `https://github.com/tutao/tutanota/releases/`,\n\t\t\t\t\t\t\t\ttarget: \"_blank\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tlang.get(\"releaseNotes_action\"),\n\t\t\t\t\t  )\n\t\t\t\t\t: null,\n\t\t\t])\n\t\t},\n\t}\n\tPromise.all([import(\"../gui/base/NotificationOverlay\"), import(\"../gui/base/Button.js\")]).then(([notificationOverlay, { ButtonType }]) => {\n\t\tnotificationOverlay.show(\n\t\t\tnotificationMessage,\n\t\t\t{\n\t\t\t\tlabel: \"postpone_action\",\n\t\t\t},\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tlabel: \"refresh_action\",\n\t\t\t\t\tclick: onUpdate,\n\t\t\t\t\ttype: ButtonType.Primary,\n\t\t\t\t},\n\t\t\t],\n\t\t)\n\t})\n}\n\nfunction showUpdateMessageIfNeeded(registration: ServiceWorkerRegistration) {\n\tconst pending = registration.waiting || registration.installing\n\n\tif (pending && registration.active) {\n\t\tshowUpdateOverlay(() => {\n\t\t\t// user has confirmed update so we have to notify the service worker to force update of version.\n\t\t\tconsole.log(\"registration.waiting: \", registration.waiting)\n\t\t\tregistration.waiting && registration.waiting.postMessage(\"update\")\n\t\t})\n\t}\n}\n\nexport function init() {\n\tconst serviceWorker = navigator.serviceWorker\n\n\tif (serviceWorker) {\n\t\t// We don't want service worker in certain envirtonments\n\t\tif (env.dist && !isApp() && !isDesktop() && window.nativeAppWebDialog == null) {\n\t\t\tconsole.log(\"Registering ServiceWorker\")\n\t\t\tserviceWorker\n\t\t\t\t.register(window.tutao.appState.prefixWithoutFile + \"/sw.js\")\n\t\t\t\t.then((registration) => {\n\t\t\t\t\tconsole.log(\"ServiceWorker has been installed\")\n\t\t\t\t\tshowUpdateMessageIfNeeded(registration)\n\t\t\t\t\tregistration.addEventListener(\"updatefound\", () => {\n\t\t\t\t\t\tconsole.log(\"updatefound\")\n\t\t\t\t\t\tshowUpdateMessageIfNeeded(registration)\n\t\t\t\t\t})\n\t\t\t\t\tconst active = registration.active // Upon registration, check if we had an sw.\n\n\t\t\t\t\tlet refreshing = false // Prevent infinite reloading with devtools\n\n\t\t\t\t\tserviceWorker.addEventListener(\"controllerchange\", (e: Event) => {\n\t\t\t\t\t\tconsole.log(\"controllerchange\")\n\n\t\t\t\t\t\tif (!active || refreshing) {\n\t\t\t\t\t\t\t// If we didn't have an sw, there's no need to reload, it's \"installation\" and not \"update\"\n\t\t\t\t\t\t\tconsole.log(`Skip refreshing: active: ${String(active)} refreshing: ${String(refreshing)}`)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\twindowFacade.windowCloseConfirmation = false\n\t\t\t\t\t\trefreshing = true\n\t\t\t\t\t\twindowFacade.reload({})\n\t\t\t\t\t})\n\t\t\t\t\tserviceWorker.addEventListener(\"message\", (event: MessageEvent) => {\n\t\t\t\t\t\tif (event.data == null || typeof event.data !== \"object\") {\n\t\t\t\t\t\t\tconsole.error(\"Got strange message from sw\", event.data)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (event.data.type === \"error\") {\n\t\t\t\t\t\t\tconst unserializedError = objToError(event.data.value)\n\t\t\t\t\t\t\thandleUncaughtError(unserializedError)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t\t.catch((e) => {\n\t\t\t\t\tconsole.warn(\"Failed to register the service worker:\", e.message)\n\n\t\t\t\t\t// We get a rejection when trying to register the service worker in firefox with security settings like\n\t\t\t\t\t// \"Delete cookies and site data and site data when Firefox is closed\" enabled\n\t\t\t\t\t// Ignore this case but still allow other cases to show an error dialog\n\t\t\t\t\tif (!(isSecurityError(e) || isNotSupportedError(e))) {\n\t\t\t\t\t\tthrow e\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t}\n\t} else {\n\t\tconsole.log(\"ServiceWorker is not supported\")\n\t}\n}\n","import { client } from \"./misc/ClientDetector\"\nimport m, { Children, ClassComponent, Component, RouteDefs, RouteResolver, Vnode, VnodeDOM } from \"mithril\"\nimport { lang, languageCodeToTag, languages } from \"./misc/LanguageViewModel\"\nimport { root } from \"./RootView\"\nimport { disableErrorHandlingDuringLogout, handleUncaughtError } from \"./misc/ErrorHandler\"\nimport { assertMainOrNodeBoot, bootFinished, isApp, isDesktop, isOfflineStorageAvailable, isTutanotaDomain } from \"./api/common/Env\"\nimport { assertNotNull, neverNull } from \"@tutao/tutanota-utils\"\nimport { windowFacade } from \"./misc/WindowFacade\"\nimport { styles } from \"./gui/styles\"\nimport { deviceConfig } from \"./misc/DeviceConfig\"\nimport { Logger, replaceNativeLogger } from \"./api/common/Logger\"\nimport { init as initSW } from \"./serviceworker/ServiceWorkerClient\"\nimport { applicationPaths } from \"./ApplicationPaths\"\nimport { ProgrammingError } from \"./api/common/error/ProgrammingError\"\nimport { NativeWebauthnView } from \"./login/NativeWebauthnView\"\nimport { WebauthnNativeBridge } from \"./native/main/WebauthnNativeBridge\"\nimport { PostLoginActions } from \"./login/PostLoginActions\"\nimport type { LoginView, LoginViewAttrs } from \"./login/LoginView.js\"\nimport type { LoginViewModel } from \"./login/LoginViewModel.js\"\nimport { TerminationView, TerminationViewAttrs } from \"./termination/TerminationView.js\"\nimport { TerminationViewModel } from \"./termination/TerminationViewModel.js\"\nimport { MobileWebauthnAttrs, MobileWebauthnView } from \"./login/MobileWebauthnView.js\"\nimport { BrowserWebauthn } from \"./misc/2fa/webauthn/BrowserWebauthn.js\"\nimport { CalendarView, CalendarViewAttrs } from \"./calendar/view/CalendarView.js\"\nimport { DrawerMenuAttrs } from \"./gui/nav/DrawerMenu.js\"\nimport { MailView, MailViewAttrs, MailViewCache } from \"./mail/view/MailView.js\"\nimport { ContactView, ContactViewAttrs } from \"./contacts/view/ContactView.js\"\nimport { SettingsView, SettingsViewAttrs } from \"./settings/SettingsView.js\"\nimport { SearchView, SearchViewAttrs } from \"./search/view/SearchView.js\"\nimport { TopLevelAttrs, TopLevelView } from \"./TopLevelView.js\"\nimport { AppHeaderAttrs } from \"./gui/Header.js\"\nimport { CalendarViewModel } from \"./calendar/view/CalendarViewModel.js\"\nimport { ExternalLoginView, ExternalLoginViewAttrs, ExternalLoginViewModel } from \"./login/ExternalLoginView.js\"\nimport { LoginController } from \"./api/main/LoginController.js\"\nimport type { MailViewModel } from \"./mail/view/MailViewModel.js\"\nimport { SearchViewModel } from \"./search/view/SearchViewModel.js\"\nimport { ContactViewModel } from \"./contacts/view/ContactViewModel.js\"\n\nassertMainOrNodeBoot()\nbootFinished()\nconst urlQueryParams = m.parseQueryString(location.search)\nconst platformId = urlQueryParams[\"platformId\"]\n\nif (isApp() || isDesktop()) {\n\tif (\n\t\t(isApp() && (platformId === \"android\" || platformId === \"ios\")) ||\n\t\t(isDesktop() && (platformId === \"linux\" || platformId === \"win32\" || platformId === \"darwin\"))\n\t) {\n\t\tenv.platformId = platformId\n\t} else {\n\t\tthrow new ProgrammingError(`Invalid platform id: ${String(platformId)}`)\n\t}\n}\n\nreplaceNativeLogger(window, new Logger())\nlet currentView: Component<unknown> | null = null\nwindow.tutao = {\n\tclient,\n\tm,\n\tlang,\n\troot,\n\tcurrentView,\n\tlocator: null,\n}\nclient.init(navigator.userAgent, navigator.platform)\n\nif (!client.isSupported()) {\n\tthrow new Error(\"Unsupported\")\n}\n\n// Setup exception handling after checking for client support, because in android the Error is caught by the unhandled rejection handler\n// and then the \"Update WebView\" message will never be show\n// we still want to do this ASAP so we can handle other errors\nsetupExceptionHandling()\nconst prefix = location.pathname[location.pathname.length - 1] !== \"/\" ? location.pathname : location.pathname.substring(0, location.pathname.length - 1)\nconst prefixWithoutFile = prefix.includes(\".\") ? prefix.substring(0, prefix.lastIndexOf(\"/\")) : prefix\n\nexport const state: { prefix: string; prefixWithoutFile: string } = { prefix, prefixWithoutFile }\nlet startRoute = \"/\"\nlet redirectTo = urlQueryParams[\"r\"] // redirection triggered by the server (e.g. the user reloads /mail/id by pressing F5)\nif (redirectTo) {\n\tdelete urlQueryParams[\"r\"]\n\n\tif (typeof redirectTo !== \"string\") {\n\t\tredirectTo = \"\"\n\t}\n} else {\n\tredirectTo = \"\"\n}\n\nlet newQueryString = m.buildQueryString(urlQueryParams)\n\nif (newQueryString.length > 0) {\n\tnewQueryString = \"?\" + newQueryString\n}\n\nlet target = redirectTo + newQueryString + location.hash\nif (target === \"\" || target[0] !== \"/\") target = \"/\" + target\nhistory.replaceState(null, \"\", assertNotNull(state.prefix) + target)\nstartRoute = target\n\n// Write it here for the WorkerClient so that it can load relative worker easily. Should do it here so that it doesn't break after HMR.\nwindow.tutao.appState = state\nlet origin = location.origin\n\nif (location.origin.indexOf(\"localhost\") !== -1) {\n\torigin += \"/client/build/index\"\n}\n\nif (!isDesktop() && typeof navigator.registerProtocolHandler === \"function\") {\n\ttry {\n\t\t// @ts-ignore third argument removed from spec, but use is still recommended\n\t\tnavigator.registerProtocolHandler(\"mailto\", origin + \"/mailto#url=%s\", \"Tutanota\")\n\t} catch (e) {\n\t\t// Catch SecurityError's and some other cases when we are not allowed to register a handler\n\t\tconsole.log(\"Failed to register a mailto: protocol handler \", e)\n\t}\n}\n\nimport(\"./translations/en\")\n\t.then((en) => lang.init(en.default))\n\t.then(async () => {\n\t\tawait import(\"./gui/main-styles\")\n\n\t\t// do this after lang initialized\n\t\tconst { locator } = await import(\"./api/main/MainLocator\")\n\t\tawait locator.init()\n\n\t\tconst { setupNavShortcuts } = await import(\"./misc/NavShortcuts.js\")\n\t\tsetupNavShortcuts()\n\n\t\t// this needs to stay after client.init\n\t\twindowFacade.init(locator.logins)\n\t\tif (isDesktop()) {\n\t\t\timport(\"./native/main/UpdatePrompt.js\").then(({ registerForUpdates }) => registerForUpdates(locator.desktopSettingsFacade))\n\t\t}\n\n\t\tconst userLanguage = deviceConfig.getLanguage() && languages.find((l) => l.code === deviceConfig.getLanguage())\n\n\t\tif (userLanguage) {\n\t\t\tconst language = {\n\t\t\t\tcode: userLanguage.code,\n\t\t\t\tlanguageTag: languageCodeToTag(userLanguage.code),\n\t\t\t}\n\t\t\tlang.setLanguage(language).catch((e) => {\n\t\t\t\tconsole.error(\"Failed to fetch translation: \" + userLanguage.code, e)\n\t\t\t})\n\n\t\t\tif (isDesktop()) {\n\t\t\t\tlocator.desktopSettingsFacade.changeLanguage(language.code, language.languageTag)\n\t\t\t}\n\t\t}\n\n\t\tconst { PostLoginActions } = await import(\"./login/PostLoginActions\")\n\t\tconst { CachePostLoginAction } = await import(\"./offline/CachePostLoginAction\")\n\t\tlocator.logins.addPostLoginAction(new PostLoginActions(locator.credentialsProvider, locator.secondFactorHandler, locator.connectivityModel))\n\t\tif (isOfflineStorageAvailable()) {\n\t\t\tlocator.logins.addPostLoginAction(\n\t\t\t\tnew CachePostLoginAction(locator.calendarModel, locator.entityClient, locator.progressTracker, locator.cacheStorage, locator.logins),\n\t\t\t)\n\t\t}\n\n\t\tstyles.init()\n\n\t\tconst paths = applicationPaths({\n\t\t\tlogin: makeViewResolver<LoginViewAttrs, LoginView, { makeViewModel: () => LoginViewModel }>(\n\t\t\t\t{\n\t\t\t\t\tprepareRoute: async () => {\n\t\t\t\t\t\tconst { LoginViewModel } = await import(\"./login/LoginViewModel.js\")\n\t\t\t\t\t\tconst { LoginView } = await import(\"./login/LoginView.js\")\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcomponent: LoginView,\n\t\t\t\t\t\t\tcache: {\n\t\t\t\t\t\t\t\tmakeViewModel: () => new LoginViewModel(locator.logins, locator.credentialsProvider, locator.secondFactorHandler, deviceConfig),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tprepareAttrs: ({ makeViewModel }) => ({ targetPath: \"/mail\", makeViewModel }),\n\t\t\t\t\trequireLogin: false,\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t\ttermination: makeViewResolver<TerminationViewAttrs, TerminationView, { makeViewModel: () => TerminationViewModel; header: AppHeaderAttrs }>(\n\t\t\t\t{\n\t\t\t\t\tprepareRoute: async () => {\n\t\t\t\t\t\tconst { TerminationViewModel } = await import(\"./termination/TerminationViewModel.js\")\n\t\t\t\t\t\tconst { TerminationView } = await import(\"./termination/TerminationView.js\")\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcomponent: TerminationView,\n\t\t\t\t\t\t\tcache: {\n\t\t\t\t\t\t\t\tmakeViewModel: () =>\n\t\t\t\t\t\t\t\t\tnew TerminationViewModel(locator.logins, locator.secondFactorHandler, locator.serviceExecutor, locator.entityClient),\n\t\t\t\t\t\t\t\theader: await locator.appHeaderAttrs(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tprepareAttrs: ({ makeViewModel, header }) => ({ makeViewModel, header }),\n\t\t\t\t\trequireLogin: false,\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t\tcontact: makeViewResolver<\n\t\t\t\tContactViewAttrs,\n\t\t\t\tContactView,\n\t\t\t\t{\n\t\t\t\t\tdrawerAttrsFactory: () => DrawerMenuAttrs\n\t\t\t\t\theader: AppHeaderAttrs\n\t\t\t\t\tcontactViewModel: ContactViewModel\n\t\t\t\t}\n\t\t\t>(\n\t\t\t\t{\n\t\t\t\t\tprepareRoute: async () => {\n\t\t\t\t\t\tconst { ContactView } = await import(\"./contacts/view/ContactView.js\")\n\t\t\t\t\t\tconst drawerAttrsFactory = await locator.drawerAttrsFactory()\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcomponent: ContactView,\n\t\t\t\t\t\t\tcache: { drawerAttrsFactory, header: await locator.appHeaderAttrs(), contactViewModel: await locator.contactViewModel() },\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tprepareAttrs: (cache) => ({ drawerAttrs: cache.drawerAttrsFactory(), header: cache.header, contactViewModel: cache.contactViewModel }),\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t\texternalLogin: makeViewResolver<ExternalLoginViewAttrs, ExternalLoginView, { header: AppHeaderAttrs; makeViewModel: () => ExternalLoginViewModel }>(\n\t\t\t\t{\n\t\t\t\t\tprepareRoute: async () => {\n\t\t\t\t\t\tconst { ExternalLoginView } = await import(\"./login/ExternalLoginView.js\")\n\t\t\t\t\t\tconst makeViewModel = await locator.externalLoginViewModelFactory()\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcomponent: ExternalLoginView,\n\t\t\t\t\t\t\tcache: { header: await locator.appHeaderAttrs(), makeViewModel },\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tprepareAttrs: ({ header, makeViewModel }) => ({ header, viewModelFactory: makeViewModel }),\n\t\t\t\t\trequireLogin: false,\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t\tmail: makeViewResolver<\n\t\t\t\tMailViewAttrs,\n\t\t\t\tMailView,\n\t\t\t\t{\n\t\t\t\t\tdrawerAttrsFactory: () => DrawerMenuAttrs\n\t\t\t\t\tcache: MailViewCache\n\t\t\t\t\theader: AppHeaderAttrs\n\t\t\t\t\tmailViewModel: MailViewModel\n\t\t\t\t}\n\t\t\t>(\n\t\t\t\t{\n\t\t\t\t\tprepareRoute: async (previousCache) => {\n\t\t\t\t\t\tconst { MailView } = await import(\"./mail/view/MailView.js\")\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcomponent: MailView,\n\t\t\t\t\t\t\tcache: previousCache ?? {\n\t\t\t\t\t\t\t\tdrawerAttrsFactory: await locator.drawerAttrsFactory(),\n\t\t\t\t\t\t\t\tcache: { mailList: null, selectedFolder: null, conversationViewModel: null, conversationViewPreference: null },\n\t\t\t\t\t\t\t\theader: await locator.appHeaderAttrs(),\n\t\t\t\t\t\t\t\tmailViewModel: await locator.mailViewModel(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tprepareAttrs: ({ drawerAttrsFactory, cache, header, mailViewModel }) => ({\n\t\t\t\t\t\tdrawerAttrs: drawerAttrsFactory(),\n\t\t\t\t\t\tcache,\n\t\t\t\t\t\theader,\n\t\t\t\t\t\tdesktopSystemFacade: locator.desktopSystemFacade,\n\t\t\t\t\t\tmailViewModel,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t\tsettings: makeViewResolver<SettingsViewAttrs, SettingsView, { drawerAttrsFactory: () => DrawerMenuAttrs; header: AppHeaderAttrs }>(\n\t\t\t\t{\n\t\t\t\t\tprepareRoute: async () => {\n\t\t\t\t\t\tconst { SettingsView } = await import(\"./settings/SettingsView.js\")\n\t\t\t\t\t\tconst drawerAttrsFactory = await locator.drawerAttrsFactory()\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcomponent: SettingsView,\n\t\t\t\t\t\t\tcache: { drawerAttrsFactory, header: await locator.appHeaderAttrs() },\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tprepareAttrs: (cache) => ({ drawerAttrs: cache.drawerAttrsFactory(), header: cache.header, logins: locator.logins }),\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t\tsearch: makeViewResolver<\n\t\t\t\tSearchViewAttrs,\n\t\t\t\tSearchView,\n\t\t\t\t{\n\t\t\t\t\tdrawerAttrsFactory: () => DrawerMenuAttrs\n\t\t\t\t\theader: AppHeaderAttrs\n\t\t\t\t\tsearchViewModelFactory: () => SearchViewModel\n\t\t\t\t}\n\t\t\t>(\n\t\t\t\t{\n\t\t\t\t\tprepareRoute: async () => {\n\t\t\t\t\t\tconst { SearchView } = await import(\"./search/view/SearchView.js\")\n\t\t\t\t\t\tconst drawerAttrsFactory = await locator.drawerAttrsFactory()\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcomponent: SearchView,\n\t\t\t\t\t\t\tcache: {\n\t\t\t\t\t\t\t\tdrawerAttrsFactory,\n\t\t\t\t\t\t\t\theader: await locator.appHeaderAttrs(),\n\t\t\t\t\t\t\t\tsearchViewModelFactory: await locator.searchViewModelFactory(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tprepareAttrs: (cache) => ({ drawerAttrs: cache.drawerAttrsFactory(), header: cache.header, makeViewModel: cache.searchViewModelFactory }),\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t\tcontactForm: makeOldViewResolver(\n\t\t\t\tasync () => {\n\t\t\t\t\tconst { ContactFormView } = await import(\"./login/contactform/ContactFormView.js\")\n\t\t\t\t\tconst header = await locator.appHeaderAttrs()\n\t\t\t\t\treturn new ContactFormView(header)\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\trequireLogin: false,\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t\tcalendar: makeViewResolver<\n\t\t\t\tCalendarViewAttrs,\n\t\t\t\tCalendarView,\n\t\t\t\t{ drawerAttrsFactory: () => DrawerMenuAttrs; header: AppHeaderAttrs; calendarViewModel: CalendarViewModel }\n\t\t\t>(\n\t\t\t\t{\n\t\t\t\t\tprepareRoute: async (cache) => {\n\t\t\t\t\t\tconst { CalendarView } = await import(\"./calendar/view/CalendarView.js\")\n\t\t\t\t\t\tconst drawerAttrsFactory = await locator.drawerAttrsFactory()\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcomponent: CalendarView,\n\t\t\t\t\t\t\tcache: cache ?? {\n\t\t\t\t\t\t\t\tdrawerAttrsFactory,\n\t\t\t\t\t\t\t\theader: await locator.appHeaderAttrs(),\n\t\t\t\t\t\t\t\tcalendarViewModel: await locator.calendarViewModel(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tprepareAttrs: ({ header, calendarViewModel, drawerAttrsFactory }) => ({ drawerAttrs: drawerAttrsFactory(), header, calendarViewModel }),\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\n\t\t\t/**\n\t\t\t * The following resolvers are programmed by hand instead of using createViewResolver() in order to be able to properly redirect\n\t\t\t * to the login page without having to deal with a ton of conditional logic in the LoginViewModel and to avoid some of the default\n\t\t\t * behaviour of resolvers created with createViewResolver(), e.g. caching.\n\t\t\t */\n\t\t\tsignup: {\n\t\t\t\tasync onmatch() {\n\t\t\t\t\tconst { showSignupDialog } = await import(\"./misc/LoginUtils\")\n\t\t\t\t\t// We have to manually parse it because mithril does not put hash into args of onmatch\n\t\t\t\t\tconst urlParams = m.parseQueryString(location.search.substring(1) + \"&\" + location.hash.substring(1))\n\t\t\t\t\tshowSignupDialog(urlParams)\n\t\t\t\t\t// when the user presses the browser back button, we would get a /login route without arguments\n\t\t\t\t\t// in the popstate event, logging us out and reloading the page before we have a chance to (asynchronously) ask for confirmation\n\t\t\t\t\t// onmatch of the login view is called after the popstate handler, but before any asynchronous operations went ahead.\n\t\t\t\t\t// duplicating the history entry allows us to keep the arguments for a single back button press and run our own code to handle it\n\t\t\t\t\tm.route.set(\"/login\", {\n\t\t\t\t\t\tnoAutoLogin: true,\n\t\t\t\t\t\tkeepSession: true,\n\t\t\t\t\t})\n\t\t\t\t\tm.route.set(\"/login\", {\n\t\t\t\t\t\tnoAutoLogin: true,\n\t\t\t\t\t\tkeepSession: true,\n\t\t\t\t\t})\n\t\t\t\t\treturn null\n\t\t\t\t},\n\t\t\t},\n\t\t\tgiftcard: {\n\t\t\t\tasync onmatch() {\n\t\t\t\t\tconst { showGiftCardDialog } = await import(\"./misc/LoginUtils\")\n\t\t\t\t\tshowGiftCardDialog(location.hash)\n\t\t\t\t\tm.route.set(\"/login\", {\n\t\t\t\t\t\tnoAutoLogin: true,\n\t\t\t\t\t\tkeepSession: true,\n\t\t\t\t\t})\n\t\t\t\t\treturn null\n\t\t\t\t},\n\t\t\t},\n\t\t\trecover: {\n\t\t\t\tasync onmatch(args: any) {\n\t\t\t\t\tconst { showRecoverDialog } = await import(\"./misc/LoginUtils\")\n\t\t\t\t\tconst resetAction = args.resetAction === \"password\" || args.resetAction === \"secondFactor\" ? args.resetAction : \"password\"\n\t\t\t\t\tconst mailAddress = typeof args.mailAddress === \"string\" ? args.mailAddress : \"\"\n\t\t\t\t\tshowRecoverDialog(mailAddress, resetAction)\n\t\t\t\t\tm.route.set(\"/login\", {\n\t\t\t\t\t\tnoAutoLogin: true,\n\t\t\t\t\t})\n\t\t\t\t\treturn null\n\t\t\t\t},\n\t\t\t},\n\t\t\twebauthn: makeOldViewResolver(\n\t\t\t\tasync () => {\n\t\t\t\t\tconst { BrowserWebauthn } = await import(\"./misc/2fa/webauthn/BrowserWebauthn.js\")\n\t\t\t\t\tconst { NativeWebauthnView } = await import(\"./login/NativeWebauthnView.js\")\n\t\t\t\t\tconst { WebauthnNativeBridge } = await import(\"./native/main/WebauthnNativeBridge.js\")\n\t\t\t\t\tconst creds = navigator.credentials\n\t\t\t\t\treturn new NativeWebauthnView(new BrowserWebauthn(creds, window.location.hostname), new WebauthnNativeBridge())\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\trequireLogin: false,\n\t\t\t\t\tcacheView: false,\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t\twebauthnmobile: makeViewResolver<MobileWebauthnAttrs, MobileWebauthnView, { browserWebauthn: BrowserWebauthn }>(\n\t\t\t\t{\n\t\t\t\t\tprepareRoute: async () => {\n\t\t\t\t\t\tconst { MobileWebauthnView } = await import(\"./login/MobileWebauthnView.js\")\n\t\t\t\t\t\tconst { BrowserWebauthn } = await import(\"./misc/2fa/webauthn/BrowserWebauthn.js\")\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcomponent: MobileWebauthnView,\n\t\t\t\t\t\t\tcache: {\n\t\t\t\t\t\t\t\tbrowserWebauthn: new BrowserWebauthn(navigator.credentials, window.location.hostname),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tprepareAttrs: (cache) => cache,\n\t\t\t\t\trequireLogin: false,\n\t\t\t\t},\n\t\t\t\tlocator.logins,\n\t\t\t),\n\t\t})\n\t\t// see https://github.com/MithrilJS/mithril.js/issues/2659\n\t\tm.route.prefix = neverNull(state.prefix).replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent)\n\t\t// keep in sync with RewriteAppResourceUrlHandler.java\n\t\tconst resolvers: RouteDefs = {\n\t\t\t\"/\": {\n\t\t\t\tonmatch: (args, requestedPath) => forceLogin(args, requestedPath),\n\t\t\t},\n\t\t}\n\n\t\tfor (let path in paths) {\n\t\t\tresolvers[path] = paths[path]\n\t\t}\n\n\t\t// append catch all at the end because mithril will stop at the first match\n\t\tresolvers[\"/:path\"] = {\n\t\t\tonmatch: async () => {\n\t\t\t\tconst { NotFoundPage } = await import(\"./gui/base/NotFoundPage.js\")\n\t\t\t\treturn {\n\t\t\t\t\tview: () => m(root, m(NotFoundPage)),\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t\t// keep in sync with RewriteAppResourceUrlHandler.java\n\t\tm.route(document.body, startRoute, resolvers)\n\n\t\t// We need to initialize native once we start the mithril routing, specifically for the case of mailto handling in android\n\t\t// If native starts telling the web side to navigate too early, mithril won't be ready and the requests will be lost\n\t\tif (isApp() || isDesktop()) {\n\t\t\tawait locator.native.init()\n\t\t}\n\t\tif (isDesktop()) {\n\t\t\tconst { exposeNativeInterface } = await import(\"./api/common/ExposeNativeInterface\")\n\t\t\tlocator.logins.addPostLoginAction(exposeNativeInterface(locator.native).postLoginActions)\n\t\t}\n\t\t// after we set up prefixWithoutFile\n\t\tinitSW()\n\t})\n\nfunction forceLogin(args: Record<string, Dict>, requestedPath: string) {\n\tif (requestedPath.indexOf(\"#mail\") !== -1) {\n\t\tm.route.set(`/ext${location.hash}`)\n\t} else if (requestedPath.startsWith(\"/#\")) {\n\t\t// we do not allow any other hashes except \"#mail\". this prevents login loops.\n\t\tm.route.set(\"/login\")\n\t} else {\n\t\tlet pathWithoutParameter = requestedPath.indexOf(\"?\") > 0 ? requestedPath.substring(0, requestedPath.indexOf(\"?\")) : requestedPath\n\n\t\tif (pathWithoutParameter.trim() === \"/\") {\n\t\t\tlet newQueryString = m.buildQueryString(args)\n\t\t\tm.route.set(`/login` + (newQueryString.length > 0 ? \"?\" + newQueryString : \"\"))\n\t\t} else {\n\t\t\tm.route.set(`/login?requestedPath=${encodeURIComponent(requestedPath)}`)\n\t\t}\n\t}\n}\n\nfunction setupExceptionHandling() {\n\twindow.addEventListener(\"error\", function (evt) {\n\t\t/**\n\t\t * evt.error is not always set, e.g. not for \"content.js:1963 Uncaught DOMException: Failed to read\n\t\t * the 'selectionStart' property from 'HTMLInputElement': The input element's type ('email')\n\t\t * does not support selection.\"\n\t\t *\n\t\t * checking for defaultPrevented is necessary to prevent devTools eval errors to be thrown in here until\n\t\t * https://chromium-review.googlesource.com/c/v8/v8/+/3660253\n\t\t * is in the chromium version used by our electron client.\n\t\t * see https://stackoverflow.com/questions/72396527/evalerror-possible-side-effect-in-debug-evaluate-in-google-chrome\n\t\t * */\n\t\tif (evt.error && !evt.defaultPrevented) {\n\t\t\thandleUncaughtError(evt.error)\n\t\t\tevt.preventDefault()\n\t\t}\n\t})\n\t// Handle unhandled native JS Promise rejections\n\twindow.addEventListener(\"unhandledrejection\", function (evt) {\n\t\thandleUncaughtError(evt.reason)\n\t\tevt.preventDefault()\n\t})\n}\n\n/**\n * Wrap top-level component with necessary logic.\n * Note: I can't make type inference work with attributes and components because of how broken mithril typedefs are so they are \"never\" by default and you\n * have to specify generic types manually.\n * @template FullAttrs type of the attributes that the component takes\n * @template ComponentType type of the component\n * @template RouteCache info that is prepared async on route change and can be used later to create attributes on every render. Is also persisted between\n * the route changes.\n * @param param\n * @param param.prepareRoute called once per route change. Use it for everything async that should happen before the route change. The result is preserved for\n * as long as RouteResolver lives if you need to persist things between routes. It receives the route cache from the previous call if there was one.\n * @param param.prepareAttrs called once per redraw. The result of it will be added to TopLevelAttrs to make full attributes.\n * @param param.requireLogin enforce login policy to either redirect to the login page or reload\n * @param logins logincontroller to ask about login state\n */\nfunction makeViewResolver<FullAttrs extends TopLevelAttrs = never, ComponentType extends TopLevelView<FullAttrs> = never, RouteCache = undefined>(\n\t{\n\t\tprepareRoute,\n\t\tprepareAttrs,\n\t\trequireLogin,\n\t}: {\n\t\tprepareRoute: (cache: RouteCache | null) => Promise<{ component: Class<ComponentType>; cache: RouteCache }>\n\t\tprepareAttrs: (cache: RouteCache) => Omit<FullAttrs, keyof TopLevelAttrs>\n\t\trequireLogin?: boolean\n\t},\n\tlogins: LoginController,\n): RouteResolver {\n\trequireLogin = requireLogin ?? true\n\tlet cache: RouteCache | null\n\n\t// a bit of context for why we do things the way we do. Constraints:\n\t//  - view must be imported async in onmatch\n\t//  - view shall not be created manually, we do not want to hold on to the instance\n\t//  - we want to pass additional parameters to the view\n\t//  - view should not be created twice and neither its dependencies\n\t//  - we either need to call updateUrl or pass requestedPath and args as attributes\n\treturn {\n\t\t// onmatch() is called for every URL change\n\t\tasync onmatch(args: Record<string, Dict>, requestedPath: string, route: string): Promise<Class<ComponentType> | null> {\n\t\t\t// enforce valid login state first.\n\t\t\t// we have views with requireLogin: true and views with requireLogin: false, each of which enforce being logged in or being logged out respectively.\n\t\t\t// in the logout case (where requireLogin: false) this will force a reload.\n\t\t\t// the login view is special in that it has requirelogin: false, but can be logged in after account creation during signup.\n\t\t\t// to handle back button presses where the user decides to stay on the page after all (we show a confirmation)\n\t\t\t// we need to prevent the logout/reload. this is the purpose of the keepSession argument.\n\t\t\t// the signup wizard that sets it handles the session itself.\n\t\t\tif (requireLogin && !logins.isUserLoggedIn()) {\n\t\t\t\tforceLogin(args, requestedPath)\n\t\t\t\treturn null\n\t\t\t} else if (!requireLogin && logins.isUserLoggedIn() && !args.keepSession) {\n\t\t\t\tawait disableErrorHandlingDuringLogout()\n\t\t\t\tawait logins.logout(false)\n\t\t\t\twindowFacade.reload(args)\n\t\t\t\treturn null\n\t\t\t} else {\n\t\t\t\tconst prepared = await prepareRoute(cache)\n\t\t\t\tcache = prepared.cache\n\t\t\t\treturn prepared.component\n\t\t\t}\n\t\t},\n\t\t// render() is called on every render\n\t\trender(vnode: Vnode<ComponentType>): Children {\n\t\t\tconst args = m.route.param()\n\t\t\tconst requestedPath = m.route.get()\n\t\t\t// result of onmatch() is passed into m() by mthril and then given to us here\n\t\t\t// It is not what we want as we want to pass few things to it but it's harmless because\n\t\t\t// it just creates a vnode but doesn't render it.\n\t\t\t// What we do is grab the class from that vnode. We could have done it differently but this\n\t\t\t// way we don't do any more caching than Mithril would do anyway.\n\n\t\t\t// TS can't prove that it's the right component and the mithril typings are generally slightly broken\n\t\t\tconst c = vnode.tag as unknown as Class<ClassComponent<FullAttrs>>\n\n\t\t\t// downcast because we ts can't really prove or enforce that additional attrs have compatible requestedPath and args\n\t\t\tconst attrs = { requestedPath, args, ...prepareAttrs(assertNotNull(cache)) } as FullAttrs\n\t\t\treturn m(\n\t\t\t\troot,\n\t\t\t\tm(c, {\n\t\t\t\t\t...attrs,\n\t\t\t\t\toncreate({ state }: VnodeDOM<FullAttrs, ComponentType>) {\n\t\t\t\t\t\twindow.tutao.currentView = state\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t)\n\t\t},\n\t}\n}\n\nfunction makeOldViewResolver(\n\tmakeView: (args: {}, requestedPath: string) => Promise<TopLevelView>,\n\t{ requireLogin, cacheView }: { requireLogin?: boolean; cacheView?: boolean } = {},\n\tlogins: LoginController,\n): RouteResolver {\n\trequireLogin = requireLogin ?? true\n\tcacheView = cacheView ?? true\n\n\tconst viewCache: { view: TopLevelView | null } = { view: null }\n\treturn {\n\t\tonmatch: async (args, requestedPath) => {\n\t\t\tif (requireLogin && !logins.isUserLoggedIn()) {\n\t\t\t\tforceLogin(args, requestedPath)\n\t\t\t} else if (!requireLogin && logins.isUserLoggedIn()) {\n\t\t\t\tawait disableErrorHandlingDuringLogout()\n\t\t\t\tawait logins.logout(false)\n\t\t\t\twindowFacade.reload(args)\n\t\t\t} else {\n\t\t\t\tlet promise: Promise<TopLevelView>\n\n\t\t\t\tif (viewCache.view == null) {\n\t\t\t\t\tpromise = makeView(args, requestedPath).then((view) => {\n\t\t\t\t\t\tif (cacheView) {\n\t\t\t\t\t\t\tviewCache.view = view\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn view\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tpromise = Promise.resolve(viewCache.view)\n\t\t\t\t}\n\n\t\t\t\tPromise.all([promise]).then(([view]) => {\n\t\t\t\t\tview.updateUrl?.(args, requestedPath)\n\t\t\t\t\tconst currentPath = m.route.get()\n\t\t\t\t\twindow.tutao.currentView = view\n\t\t\t\t})\n\t\t\t\treturn promise\n\t\t\t}\n\t\t},\n\t\trender: (vnode) => {\n\t\t\treturn m(root, vnode)\n\t\t},\n\t}\n}\n\nenv.dist &&\n\tisTutanotaDomain(location.hostname) &&\n\tsetTimeout(() => {\n\t\tconsole.log(`\n\n''''''''''''''''''''''''''''''''''''''''\n''''''''''''''''''''''''''''''''''''''''\n''''''''''''''''''''''''''''''''''''''''\n''''''''''''''''''''''''''''''''''''''''\n''''''''''''''''''''''''''''''''''''''''\n''''''''''''''''''''''''''''''''''''''''\n''''''''''''''''''''''''',:,''''''''''''\n''''''''''''';:llllcccccccc,''''''''''''    Do you care about privacy?\n'''''''''''':kXWXkoc::;,,'''''''''''''''\n'''''''''''',cdk0KKK00kxdolc;,''''''''''    Work at Tutanota! Fight for our rights!\n'''''''''''''''';coxOKNMMWWNK0kdl:,'''''\n'''''''''''''''''''',;oKMMMMMMMMWX0dc,''    https://tutanota.com/jobs\n'''''''''''''''''''''';kWMMMMMMMMMMWXk:'\n'''''''''''''''''''',:xXMMMMMMMMMMMMMWKl\n''''''''''''''''';lk0KWMMMMMMMMMMMMMMMWK\n''''''''''''';cdOKWMMMMMMMMMMMMMMMMMMMMM\n'''''''',:ldOKNWMMMMMMMMMMMMMMMMMMMMMMMM\n''',:ldk0XWMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\nldk0XWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\nWWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n\n`)\n\t}, 5000)\n","// @bundleInto:boot\n\nimport { RouteResolver } from \"mithril\"\n\nexport type ApplicationPaths = Record<string, RouteResolver>\ntype ViewResolvers = {\n\tlogin: RouteResolver\n\ttermination: RouteResolver\n\tmail: RouteResolver\n\texternalLogin: RouteResolver\n\tcontact: RouteResolver\n\tsearch: RouteResolver\n\tsettings: RouteResolver\n\tcontactForm: RouteResolver\n\tcalendar: RouteResolver\n\tsignup: RouteResolver\n\tgiftcard: RouteResolver\n\trecover: RouteResolver\n\twebauthn: RouteResolver\n\twebauthnmobile: RouteResolver\n}\n\nexport function applicationPaths({\n\tlogin,\n\ttermination,\n\tmail,\n\texternalLogin,\n\tcontact,\n\tsearch,\n\tsettings,\n\tcontactForm,\n\tcalendar,\n\tsignup,\n\tgiftcard,\n\trecover,\n\twebauthn,\n\twebauthnmobile,\n}: ViewResolvers): ApplicationPaths {\n\treturn {\n\t\t\"/login\": login,\n\t\t\"/termination\": termination,\n\t\t\"/signup\": signup,\n\t\t\"/recover\": recover,\n\t\t\"/mailto\": mail,\n\t\t\"/mail\": mail,\n\t\t\"/mail/:listId\": mail,\n\t\t\"/mail/:listId/:mailId\": mail,\n\t\t\"/ext\": externalLogin,\n\t\t\"/contact\": contact,\n\t\t\"/contact/:listId\": contact,\n\t\t\"/contact/:listId/:contactId\": contact,\n\t\t\"/search/:category\": search,\n\t\t\"/search/:category/:id\": search,\n\t\t\"/settings\": settings,\n\t\t\"/settings/:folder\": settings,\n\t\t\"/settings/:folder/:id\": settings,\n\t\t\"/contactform/:formId\": contactForm,\n\t\t\"/calendar\": calendar,\n\t\t\"/calendar/:view\": calendar,\n\t\t\"/calendar/:view/:date\": calendar,\n\t\t\"/giftcard/\": giftcard,\n\t\t\"/webauthn\": webauthn,\n\t\t\"/webauthnmobile\": webauthnmobile,\n\t}\n}\n\nexport function getPathBases(): Array<string> {\n\tconst paths = Object.keys(applicationPaths({} as any))\n\tconst uniquePathBases = new Set(paths.map((path) => path.split(\"/\")[1]))\n\treturn Array.from(uniquePathBases)\n}\n","import type { DeferredObject } from \"@tutao/tutanota-utils\"\nimport { assertNotNull, defer } from \"@tutao/tutanota-utils\"\nimport { assertMainOrNodeBoot } from \"../common/Env\"\nimport type { UserController, UserControllerInitData } from \"./UserController\"\nimport { getWhitelabelCustomizations } from \"../../misc/WhitelabelCustomizations\"\nimport { NotFoundError } from \"../common/error/RestError\"\nimport { client } from \"../../misc/ClientDetector\"\nimport type { LoginFacade, NewSessionData } from \"../worker/facades/LoginFacade\"\nimport { ResumeSessionErrorReason } from \"../worker/facades/LoginFacade\"\nimport type { Credentials } from \"../../misc/credentials/Credentials\"\nimport { FeatureType } from \"../common/TutanotaConstants\"\nimport { CredentialsAndDatabaseKey } from \"../../misc/credentials/CredentialsProvider.js\"\nimport { SessionType } from \"../common/SessionType\"\nimport { IMainLocator, locator } from \"./MainLocator\"\n\nassertMainOrNodeBoot()\n\nexport interface IPostLoginAction {\n\t/** Partial login is achieved with getting the user, can happen offline. The login will wait for the returned promise. */\n\tonPartialLoginSuccess(loggedInEvent: LoggedInEvent): Promise<void>\n\n\t/** Full login is achieved with getting group keys. Can do service calls from this point on. */\n\tonFullLoginSuccess(loggedInEvent: LoggedInEvent): Promise<void>\n}\n\nexport type LoggedInEvent = {\n\treadonly sessionType: SessionType\n\treadonly userId: Id\n}\n\nexport type ResumeSessionResult = { type: \"success\" } | { type: \"error\"; reason: ResumeSessionErrorReason }\n\nexport class LoginController {\n\tprivate userController: UserController | null = null\n\tprivate customizations: NumberString[] | null = null\n\tprivate partialLogin: DeferredObject<void> = defer()\n\tprivate _isWhitelabel: boolean = !!getWhitelabelCustomizations(window)\n\tprivate postLoginActions: Array<IPostLoginAction> = []\n\tprivate fullyLoggedIn: boolean = false\n\tprivate atLeastPartiallyLoggedIn: boolean = false\n\n\tinit() {\n\t\tthis.waitForFullLogin().then(async () => {\n\t\t\tthis.fullyLoggedIn = true\n\t\t\tawait this.waitForPartialLogin()\n\t\t\tfor (const action of this.postLoginActions) {\n\t\t\t\tawait action.onFullLoginSuccess({\n\t\t\t\t\tsessionType: this.getUserController().sessionType,\n\t\t\t\t\tuserId: this.getUserController().userId,\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate async getMainLocator(): Promise<IMainLocator> {\n\t\tconst { locator } = await import(\"./MainLocator\")\n\t\tawait locator.initialized\n\t\treturn locator\n\t}\n\n\tprivate async getLoginFacade(): Promise<LoginFacade> {\n\t\tconst locator = await this.getMainLocator()\n\t\tconst worker = locator.worker\n\t\tawait worker.initialized\n\t\treturn locator.loginFacade\n\t}\n\n\t/**\n\t * create a new session and set up stored credentials and offline database, if applicable.\n\t * @param username the mail address being used to log in\n\t * @param password the password given to log in\n\t * @param sessionType whether to store the credentials in local storage\n\t * @param databaseKey if given, will use this key for the offline database. if not, will force a new database to be created and generate a key.\n\t */\n\tasync createSession(username: string, password: string, sessionType: SessionType, databaseKey: Uint8Array | null = null): Promise<NewSessionData> {\n\t\tconst loginFacade = await this.getLoginFacade()\n\t\tconst newSessionData = await loginFacade.createSession(username, password, client.getIdentifier(), sessionType, databaseKey)\n\t\tconst { user, credentials, sessionId, userGroupInfo } = newSessionData\n\t\tawait this.onPartialLoginSuccess(\n\t\t\t{\n\t\t\t\tuser,\n\t\t\t\tuserGroupInfo,\n\t\t\t\tsessionId,\n\t\t\t\taccessToken: credentials.accessToken,\n\t\t\t\tsessionType,\n\t\t\t},\n\t\t\tsessionType,\n\t\t)\n\t\treturn newSessionData\n\t}\n\n\taddPostLoginAction(handler: IPostLoginAction) {\n\t\tthis.postLoginActions.push(handler)\n\t}\n\n\tasync onPartialLoginSuccess(initData: UserControllerInitData, sessionType: SessionType): Promise<void> {\n\t\tconst { initUserController } = await import(\"./UserController\")\n\t\tthis.userController = await initUserController(initData)\n\n\t\tawait this.loadCustomizations()\n\t\tawait this._determineIfWhitelabel()\n\n\t\tfor (const handler of this.postLoginActions) {\n\t\t\tawait handler.onPartialLoginSuccess({\n\t\t\t\tsessionType,\n\t\t\t\tuserId: initData.user._id,\n\t\t\t})\n\t\t}\n\t\tthis.atLeastPartiallyLoggedIn = true\n\t\tthis.partialLogin.resolve()\n\t}\n\n\tasync createExternalSession(userId: Id, password: string, salt: Uint8Array, clientIdentifier: string, sessionType: SessionType): Promise<Credentials> {\n\t\tconst loginFacade = await this.getLoginFacade()\n\t\tconst persistentSession = sessionType === SessionType.Persistent\n\t\tconst { user, credentials, sessionId, userGroupInfo } = await loginFacade.createExternalSession(\n\t\t\tuserId,\n\t\t\tpassword,\n\t\t\tsalt,\n\t\t\tclientIdentifier,\n\t\t\tpersistentSession,\n\t\t)\n\t\tawait this.onPartialLoginSuccess(\n\t\t\t{\n\t\t\t\tuser,\n\t\t\t\taccessToken: credentials.accessToken,\n\t\t\t\tsessionType,\n\t\t\t\tsessionId,\n\t\t\t\tuserGroupInfo,\n\t\t\t},\n\t\t\tSessionType.Login,\n\t\t)\n\t\treturn credentials\n\t}\n\n\t/**\n\t * Resume an existing session using stored credentials, may or may not unlock a persistent local database\n\t * @param credentials: The stored credentials and optional database key for the offline db\n\t * @param externalUserSalt\n\t * @param offlineTimeRangeDays: the user configured time range for their offline storage, used to initialize the offline db\n\t */\n\tasync resumeSession(\n\t\t{ credentials, databaseKey }: CredentialsAndDatabaseKey,\n\t\texternalUserSalt?: Uint8Array | null,\n\t\tofflineTimeRangeDays?: number | null,\n\t): Promise<ResumeSessionResult> {\n\t\tconst loginFacade = await this.getLoginFacade()\n\t\tconst resumeResult = await loginFacade.resumeSession(credentials, externalUserSalt ?? null, databaseKey ?? null, offlineTimeRangeDays ?? null)\n\t\tif (resumeResult.type === \"error\") {\n\t\t\treturn resumeResult\n\t\t} else {\n\t\t\tconst { user, userGroupInfo, sessionId } = resumeResult.data\n\t\t\tawait this.onPartialLoginSuccess(\n\t\t\t\t{\n\t\t\t\t\tuser,\n\t\t\t\t\taccessToken: credentials.accessToken,\n\t\t\t\t\tuserGroupInfo,\n\t\t\t\t\tsessionId,\n\t\t\t\t\tsessionType: SessionType.Persistent,\n\t\t\t\t},\n\t\t\t\tSessionType.Persistent,\n\t\t\t)\n\t\t\treturn { type: \"success\" }\n\t\t}\n\t}\n\n\tisUserLoggedIn(): boolean {\n\t\treturn this.userController != null\n\t}\n\n\tisFullyLoggedIn(): boolean {\n\t\treturn this.fullyLoggedIn\n\t}\n\n\tisAtLeastPartiallyLoggedIn(): boolean {\n\t\treturn this.atLeastPartiallyLoggedIn\n\t}\n\n\twaitForPartialLogin(): Promise<void> {\n\t\treturn this.partialLogin.promise\n\t}\n\n\tasync waitForFullLogin(): Promise<void> {\n\t\tconst locator = await this.getMainLocator()\n\t\t// Full login event might be received before we finish userLogin on the client side because they are done in parallel.\n\t\t// So we make sure to wait for userLogin first.\n\t\tawait this.waitForPartialLogin()\n\t\treturn locator.loginListener.waitForFullLogin()\n\t}\n\n\tisInternalUserLoggedIn(): boolean {\n\t\treturn this.isUserLoggedIn() && this.getUserController().isInternalUser()\n\t}\n\n\tisGlobalAdminUserLoggedIn(): boolean {\n\t\treturn this.isUserLoggedIn() && this.getUserController().isGlobalAdmin()\n\t}\n\n\tgetUserController(): UserController {\n\t\treturn assertNotNull(this.userController) // only to be used after login (when user is defined)\n\t}\n\n\tisEnabled(feature: FeatureType): boolean {\n\t\treturn this.customizations != null ? this.customizations.indexOf(feature) !== -1 : false\n\t}\n\n\tloadCustomizations(): Promise<void> {\n\t\tif (this.isInternalUserLoggedIn()) {\n\t\t\treturn this.getUserController()\n\t\t\t\t.loadCustomer()\n\t\t\t\t.then((customer) => {\n\t\t\t\t\tthis.customizations = customer.customizations.map((f) => f.feature)\n\t\t\t\t})\n\t\t} else {\n\t\t\treturn Promise.resolve()\n\t\t}\n\t}\n\n\tasync logout(sync: boolean): Promise<void> {\n\t\tif (this.userController) {\n\t\t\tawait this.userController.deleteSession(sync)\n\t\t\tthis.userController = null\n\t\t\tthis.partialLogin = defer()\n\t\t\tthis.fullyLoggedIn = false\n\t\t\tconst locator = await this.getMainLocator()\n\t\t\tlocator.loginListener.reset()\n\t\t\tthis.init()\n\t\t} else {\n\t\t\tconsole.log(\"No session to delete\")\n\t\t}\n\t}\n\n\tasync _determineIfWhitelabel(): Promise<void> {\n\t\tthis._isWhitelabel = await this.getUserController().isWhitelabelAccount()\n\t}\n\n\tisWhitelabel(): boolean {\n\t\treturn this._isWhitelabel\n\t}\n\n\tasync deleteOldSession(credentials: Credentials): Promise<void> {\n\t\tconst loginFacade = await this.getLoginFacade()\n\n\t\ttry {\n\t\t\tawait loginFacade.deleteSession(credentials.accessToken)\n\t\t} catch (e) {\n\t\t\tif (e instanceof NotFoundError) {\n\t\t\t\tconsole.log(\"session already deleted\")\n\t\t\t} else {\n\t\t\t\tthrow e\n\t\t\t}\n\t\t}\n\t}\n\n\tasync retryAsyncLogin() {\n\t\tconst loginFacade = await this.getLoginFacade()\n\t\tconst locator = await this.getMainLocator()\n\t\tlocator.loginListener.onRetryLogin()\n\t\tawait loginFacade.retryAsyncLogin()\n\t}\n}\n"],"names":["top","right","bottom","left","position","positionValue","bottomInsetString","getComputedStyle","assertNotNull","document","body","getPropertyValue","parseInt","slice","type","begin","end","values","updateDom","target","percent","easing","style","transform","types","Object","keys","TransformUnits","value","calculateValue","push","join","buildTransformString","willChange","chain","component","createAnimation","closeAnimation","shadowClass","newAttrs","pair","key","overlays","async","dom","animation","animations","add","duration","ease","in","Promise","resolve","remove","m","redraw","role","label","class","tabindex","element","marginRight","marginLeft","whitelabelConfig","JSON","parse","jsonTheme","k","v","undefined","lastCall","url","args","now","Date","getTime","route","set","replace","e","message","includes","console","log","theme","navigation_menu_bg","navigation_bg","window","orientation","width","getLogoSvg","content_accent","isColorLight","content_bg","logo_text_dark_grey","logo_text_bright_grey","height","client","isDesktopDevice","addEventListener","flashIn","eventListenerArgs","flashOut","PREVENT","passive","content_button_icon_bg","content_button","elevated_bg","removeEventListener","navigation_menu_icon","navigation_button_icon","navigation_button_icon_bg","navigation_button","assertMainOrNodeBoot","exports","constructor","init","userAgent","platform","this","browser","browserVersion","device","_setBrowserAndVersion","_setDeviceInfo","overflowAuto","cssPropertyValueSupported","isMacOS","indexOf","syntaxChecks","arrowFunction","aLet","testGenerator","testAsync","anArray","propertyShorthand","x","y","x2","y2","a1","a2","arest","item","testBuiltins","Set","Map","Array","prototype","entries","fromEntries","Symbol","Uint8Array","Proxy","Reflect","finally","testCss","querySelector","querySelectorAll","isSupported","isSupportedBrowserVersion","websockets","isMobileDevice","WebSocket","CLOSING","localStorage","history","xhr2","indexedDb","indexedDB","operaIndex1","operaIndex2","firefoxIndex","paleMoonIndex","iceweaselIndex","chromeIndex","chromeIosIndex","safariIndex","edgeIndex","androidIndex","versionIndex","extractIosVersion","match","mainVersionEndIndex","Number","substring","pos","hadNan","length","isNaN","charAt","numberString","test","TouchEvent","isTouchSupported","isIos","prop","d","createElement","getIdentifier","env","mode","Mode","App","Browser","platformId","notOldFirefox","notOldChrome","needsMicrotaskHack","needsExplicitIDBIds","browserData","indexedDbSupported","getWhitelabelCustomizations","whitelabelCustomizations","Vnode","tag","attrs0","children","text","attrs","domSize","state","events","instance","normalize","node","isArray","normalizeChildren","String","input","isKeyed","i","TypeError","hyperscriptVnode","children0","attrs1","arguments","start","hasOwn","hasOwnProperty","selectorParser","selectorCache","isEmpty","object","call","hyperscript","selector","view","Error","vnode","apply","hasClass","className","execSelector","classes","exec","id","attrValue","compileSelector","trust","html","fragment","vnode2","render","$window","currentRedraw","$doc","nameSpace","svg","math","getNameSpace","vnode3","xmlns","checkState","original","callHook","activeElement","createNodes","parent","vnodes","hooks","nextSibling","ns","createNode","initLifecycle","createTextNode","insertNode","createText","createHTML","createDocumentFragment","children2","firstChild","childNodes","createFragment","attrs2","is","createElementNS","setAttribute","isFileInput","setAttr","setAttrs","maybeSetContentEditable","selectedIndex","normalized","setLateSelectAttrs","sentinel","create","$$reentrantLock$$","initComponent","createComponent","possibleParents","caption","thead","tbody","tfoot","tr","th","td","colgroup","col","match0","temp","innerHTML","child","appendChild","updateNodes","old","removeNodes","isOldKeyed","isKeyed0","oldStart","o","oe","ve","topSibling","oldEnd","updateNode","getNextSibling","moveNodes","map","lisIndices","originalNextSibling","vnodesLength","oldIndices","li","matched","getKeyMap","oldIndex","a","result","u","il","lisTemp","j","c","makeLisIndices","commonLength","removeNode","oldTag","force","onbeforeupdate","shouldNotUpdate","updateLifecycle","toString","nodeValue","updateText","removeHTML","updateHTML","updateFragment","warn","val","removeAttr","updateAttrs","updateElement","updateComponent","frag","moveChildToFrag","parentNode","insertBefore","contenteditable","contentEditable","content","stateResult","attrsResult","mask","onbeforeremove","then","next","reallyRemove","onremove","removeChild","isLifecycleMethod","attr","isFormAttribute","updateEvent","setAttributeNS","updateStyle","hasPropertyKey","error","removeAttribute","nsLastIndex","currentDOM","uppercaseRegex","toLowerCase","capital","normalizeKey","cssText","setProperty","removeProperty","EventDict","_","source","oninit","oncreate","bind","onupdate","handleEvent","ev","handler0","currentTarget","preventDefault","stopPropagation","contains","prevRedraw","prevDOM","active","namespace","namespaceURI","textContent","focus","_13","mountRedraw0","render0","schedule","subscriptions","pending","offset","sync","mount","root","index","splice","_16","requestAnimationFrame","buildQueryString","key2","destructure","value1","encodeURIComponent","assign","key3","buildPathname","template","params","SyntaxError","queryIndex","hashIndex","queryEnd","pathEnd","path","query","resolved","m4","key1","variadic","newQueryIndex","newHashIndex","newQueryEnd","newPathEnd","result0","querystring","mountRedraw","Fragment","m6","decodeURIComponentSave0","str","decodeURIComponent","err","parseQueryString","string","split","counters","data0","entry","key5","value2","levels","cursor","pop","j0","level","nextLevel","isNumber","desc","getOwnPropertyDescriptor","parsePathname","queryIndex0","hashIndex0","queryEnd0","pathEnd0","path1","magic","RegExp","censor","attrs4","extras","result2","key7","sentinel0","decodeURIComponentSave","mountRedraw00","compiled","fallbackRoute","attrs3","currentPath","lastUpdate","callAsync0","setImmediate","setTimeout","p","scheduled","ready","currentResolver","RouterRoot","fireAsync","resolveRoute","vnode5","SKIP","prefix","location","hash","search","pathname","path0","concat","data","reject","setPath","loop","check","payload","matchedRoute","localComp","update","comp","onmatch","options","title","replaceState","pushState","href","defaultRoute","routes","templateData","templateKeys","regexp","m7","key6","extra","r","data1","defaultData","some","ReferenceError","get","Link","onclick","child0","disabled","Boolean","result1","defaultPrevented","button","which","ctrlKey","metaKey","shiftKey","altKey","param","key4","_28","module","translationImportMap","ar","import","be","bg","ca","cs","da","de","de_sie","el","en","en_gb","es","et","fa_ir","fi","fr","gl","he","hi","hr","hu","it","ja","ko","lt","lv","nl","no","pl","pt_br","pt_pt","ro","ru","si","sk","sl","sr_cyrl","sv","uk","vi","zh","zh_hant","LanguageNames","freeze","languageByCode","code","textId","downcast","languages","typedEntries","LanguageViewModel","translations","fallback","staticTranslations","language","getLanguage","setLanguage","catch","_setLanguageTag","addStaticTranslation","initWithTranslations","languageTag","fallBackTranslations","lang","startsWith","translationsModule","default","updateFormats","formats","simpleDate","Intl","DateTimeFormat","day","month","year","dateWithMonth","dateWithoutYear","simpleDateWithoutYear","dateWithWeekday","weekday","dateWithWeekdayWoMonth","dateWithWeekdayAndYear","dateWithWeekdayAndYearLong","dateWithWeekdayAndTime","hour","minute","time","dateTime","dateTimeShort","weekdayShort","weekdayNarrow","priceWithCurrency","NumberFormat","currency","minimumFractionDigits","priceWithCurrencyWithoutFractionDigits","maximumFractionDigits","priceWithoutCurrency","priceWithoutCurrencyWithoutFractionDigits","monthLong","monthWithYear","monthWithFullYear","yearNumeric","exists","replacements","replaceAll","getMaybeLazy","getLanguageNoDefault","restrictions","languageTags","navigator","process","locale","LC_ALL","LC_MESSAGES","LANG","LANGUAGE","LC_NAME","getSubstitutedLanguageCode","find","l","basePart","getBasePart","customizations","germanCode","germanLanguageCode","indexOfUnderscore","getAvailableLanguageCode","languageCodeToTag","before","after","toUpperCase","assertTranslation","EasingType","Math","pow","out","inOut","linear","VALID_HEX_CODE_FORMAT","g","b","hexToRgb","colorCode","assert","hexWithoutHash","expandHexTriplet","rgb","triplet","from","reduce","acc","cur","DefaultAnimationTime","InitializedOptions","stagger","delay","Animations","activeAnimations","_animate","finished","performance","animateFrame","isFinished","targets","mutations","targetsArray","HTMLElement","targetMutations","verifiedOptions","verifiyOptions","mutation","filter","forEach","t","promise","Animation","animationPromise","cancel","static","animationStart","runTime","min","translateX","translateY","rotateY","rotateZ","scale","alpha","colorHex","color","alphaChannel","backgroundColor","opacity","keepValue","initialOpacity","defaultThemeId","DeviceConfig","_version","loadedConfig","_a","loadConfigFromLocalStorage","signupToken","doSave","Version","ProgrammingError","_credentials","oldCredentialsArray","credential","login","mailAddress","userId","credentialInfo","encryptedPassword","accessToken","migrateConfigV2to3","migrateConfig","_signupToken","bytes","crypto","getRandomValues","uint8ArrayToBase64","config","_credentialEncryptionMode","_b","_encryptedCredentialsKey","_c","acknowledgedNewsItems","_d","_themeId","_e","scheduledAlarmModelVersionPerUser","_f","_language","_g","_defaultCalendarView","_h","_hiddenCalendars","_j","expandedMailFolders","_k","_testDeviceId","_l","_testAssignments","_m","offlineTimeRangeDaysByUser","_o","conversationViewShowOnlySelectedMail","_p","writeToStorage","loadedConfigString","getItem","LocalStorageKey","store","persistentCredentials","existing","databaseKey","loadByUserId","loadAll","deleteByUserId","delete","getSignupToken","getScheduledAlarmsModelVersion","setScheduledAlarmsModelVersion","version","setNoAlarmsScheduled","setItem","stringify","getTheme","setTheme","getDefaultCalendarView","setDefaultCalendarView","defaultView","getHiddenCalendars","user","setHiddenCalendars","calendars","getExpandedFolders","setExpandedFolders","folders","hasAcknowledgedNewsItemForDevice","newsItemId","acknowledgeNewsItemForDevice","getCredentialEncryptionMode","setCredentialEncryptionMode","encryptionMode","getCredentialsEncryptionKey","base64ToUint8Array","setCredentialsEncryptionKey","testDeviceId","persistedAssignmentData","getOfflineTimeRangeDays","setOfflineTimeRangeDays","days","getConversationViewShowOnlySelectedMail","setConversationViewShowOnlySelectedMail","setting","deviceConfig","highlightColor","textColor","light_white","grey_lighter_4","grey_lighter_3","grey_lighter_2","grey_lighter_1","grey_lighter_0","grey","grey_darker_0","grey_darker_1","red","blue","light_lighter_1","light_lighter_0","dark_lighter_2","dark_lighter_1","dark_lighter_0","dark_darker_0","green","themes","light","themeId","logo","button_bubble_bg","button_bubble_fg","content_fg","content_button_selected","content_button_icon","content_button_icon_selected","content_border","content_message_bg","header_bg","header_box_shadow_bg","header_button","header_button_selected","list_bg","list_alternate_bg","list_accent_fg","list_message_bg","list_border","modal_bg","navigation_border","navigation_button_selected","navigation_button_icon_selected","dark","selectedThemeFacade","isApp","isDesktop","themeFacade","LazyLoaded","locator","n","bO","initialized","getAsync","getSelectedTheme","setSelectedTheme","dispatcher","getThemes","setThemes","_deviceConfig","sanitizerStub","sanitizeHTML","externalContent","inlineImageCids","links","sanitizeSVG","configExtra","sanitizeFragment","themeController","htmlSanitizer","_theme","getDefaultTheme","themeIdChangedStream","stream","all","_initializeTheme","_updateBuiltinThemes","updateCustomTheme","themeJson","URL","searchParams","parsedTheme","_parseCustomizations","reloadTheme","stringTheme","typedValues","updateSavedThemeDefinition","setThemeId","customTheme","_sanitizeTheme","getCurrentTheme","newThemeId","permanent","newTheme","_getTheme","_applyTrustedTheme","updatedTheme","assembleTheme","filledWithoutLogo","nonNullTheme","oldThemes","findAndRemove","getBaseTheme","baseId","shouldAllowChangingTheme","base","themeWithoutLogo","coloredTutanotaLogo","mapAndFilterNull","isTest","TABBABLE","focusPrevious","tabbable","display","tabIndex","selected","selection","getSelection","focusNode","nodeName","mod","focusNext","createKeyIdentifier","keycode","ctrl","alt","shift","meta","isKeyPressed","keyCode","keyManager","_isHelpOpen","helpShortcut","Keys","F1","openF1Help","help","helpId","_keyToShortcut","_keyToModalShortcut","_desktopShortcuts","_handleKeydown","shortcut","size","enabled","forceBaseShortcuts","shortcutsToShow","bP","showShortcutDialog","registerShortcuts","shortcuts","META","_applyOperation","s","unregisterShortcuts","registerDesktopShortcuts","registerModalShortcuts","unregisterModalShortcuts","operation","WindowFacade","_historyStateEventListeners","_indexerFacade","_keyboardSize","_keyboardSizeListeners","_ignoreNextPopstate","logins","_windowSizeListeners","resizeTimeout","windowCloseConfirmation","_windowCloseListeners","indexerFacade","connectivityModel","Desktop","Admin","addPageInBackgroundListener","onresize","cb","_resize","onorientationchange","addResizeListener","listener","removeResizeListener","addWindowCloseListener","_checkWindowClosing","_notifyCloseListeners","f","addKeyboardSizeListener","removeKeyboardSizeListener","openLink","open","_beforeUnload","_popState","_onUnload","tagName","back","forward","innerWidth","innerHeight","enable","returnValue","logout","addHistoryEventListener","removeHistoryEventListener","len","go","addOnlineListener","addOfflineListener","isElectronClient","noAutoLogin","stringifiedArgs","commonSystemFacade","reload","isIOSApp","hidden","onVisibilityChanged","tryReconnect","onKeyboardSizeChanged","windowFacade","modal","_historyEventListener","currentKey","components","visible","_uniqueComponent","_closingComponents","wrapper","array","needsBg","addAnimation","event","firstElementChild","childRect","getBoundingClientRect","insideRect","backgroundClick","zIndex","hideAnimation","existingIndex","findIndex","shownComponent","_getComponentByKey","popState","displayUnique","componentIndex","componentIsTopmostComponent","domLayer","fadein","overlay","overlayAttrs","Cat","name","activeCategories","category","icon_size_xl","icon_size_large","icon_size_medium","icon_message_box","hpad_small","hpad","hpad_medium","hpad_large","hpad_large_mobile","hpad_button","hpad_nav_button","vpad_xs","vpad","vpad_small","vpad_ml","vpad_large","vpad_xl","text_bubble_tpad","border_radius_small","border_radius","border_radius_big","border_selection","font_size_base","font_size_smaller","font_size_small","button_height","button_height_accent","button_height_bubble","button_height_compact","button_icon_bg_size","button_floating_size","navbar_height","navbar_height_mobile","bottom_nav_bar","navbar_button_width","navbar_edge_width_mobile","header_logo_height","header_logo_height_mobile","list_row_height","column_width_s_desktop","column_width_s_mobile","line_height","line_height_m","line_height_l","calendar_line_height","calendar_hour_height","calendar_event_border","calendar_day_event_padding","calendar_hour_width","calendar_hour_width_mobile","calendar_event_margin","calendar_event_margin_mobile","drawer_menu_width","first_col_min_width","first_col_max_width","second_col_min_width","second_col_max_width","third_col_min_width","third_col_max_width","desktop_layout_width","two_column_layout_width","dot_size","checkbox_size","px","objectToCss","indent","cssString","toCss","obj","ret","styles","styleSheets","bodyWidth","neverNull","offsetWidth","bodyHeight","offsetHeight","updateDomStyles","getStyleSheetElement","cloneNode","isDesktopLayout","isSingleColumnLayout","isUsingBottomNavigation","isAdminClient","registerStyle","styleCreator","has","updateDomStyle","creator","round","timer","styleSheet","getDomStyleSheet","styleDomElement","getElementById","getElementsByTagName","currentNavigationType","onpointerup","pointerType","switchNavType","onkeyup","TAB","classForType","newType","classList","importErrorHandler","ms","fn","lastTry","previousTry","sincePreviousTry","timeUntilWaitEnd","produceThrottledFunction","bS","handleUncaughtError","stack","handleUncaughtErrorImpl","disableErrorHandlingDuringLogout","showUpdateMessageIfNeeded","registration","waiting","installing","onUpdate","notificationMessage","isTutanotaDomain","hostname","aw","au","notificationOverlay","ButtonType","show","click","showUpdateOverlay","postMessage","bootFinished","urlQueryParams","replaceNativeLogger","Logger","tutao","currentView","evt","reason","prefixWithoutFile","lastIndexOf","startRoute","redirectTo","newQueryString","appState","origin","registerProtocolHandler","forceLogin","requestedPath","trim","makeViewResolver","prepareRoute","prepareAttrs","requireLogin","cache","isUserLoggedIn","keepSession","prepared","makeOldViewResolver","makeView","cacheView","viewCache","updateUrl","bT","setupNavShortcuts","bU","U","registerForUpdates","desktopSettingsFacade","userLanguage","changeLanguage","PostLoginActions","P","CachePostLoginAction","fc","addPostLoginAction","credentialsProvider","secondFactorHandler","isOfflineStorageAvailable","calendarModel","entityClient","progressTracker","cacheStorage","paths","termination","mail","externalLogin","contact","settings","contactForm","calendar","signup","giftcard","recover","webauthn","webauthnmobile","applicationPaths","LoginViewModel","LoginView","makeViewModel","targetPath","TerminationViewModel","T","TerminationView","serviceExecutor","header","appHeaderAttrs","ContactView","drawerAttrsFactory","contactViewModel","drawerAttrs","ExternalLoginView","E","externalLoginViewModelFactory","viewModelFactory","previousCache","MailView","mailList","selectedFolder","conversationViewModel","conversationViewPreference","mailViewModel","desktopSystemFacade","SettingsView","SearchView","searchViewModelFactory","ContactFormView","C","CalendarView","calendarViewModel","showSignupDialog","bV","showGiftCardDialog","showRecoverDialog","resetAction","BrowserWebauthn","bN","NativeWebauthnView","N","WebauthnNativeBridge","W","credentials","MobileWebauthnView","M","browserWebauthn","resolvers","NotFoundPage","ax","native","exposeNativeInterface","fe","postLoginActions","serviceWorker","dist","nativeAppWebDialog","register","refreshing","objToError","isSecurityError","isNotSupportedError","initSW","userController","partialLogin","defer","_isWhitelabel","fullyLoggedIn","atLeastPartiallyLoggedIn","waitForFullLogin","waitForPartialLogin","action","onFullLoginSuccess","sessionType","getUserController","getMainLocator","worker","loginFacade","username","password","getLoginFacade","newSessionData","createSession","sessionId","userGroupInfo","onPartialLoginSuccess","handler","initData","initUserController","bW","loadCustomizations","_determineIfWhitelabel","_id","salt","clientIdentifier","persistentSession","createExternalSession","externalUserSalt","offlineTimeRangeDays","resumeResult","resumeSession","isFullyLoggedIn","isAtLeastPartiallyLoggedIn","loginListener","isInternalUserLoggedIn","isInternalUser","isGlobalAdminUserLoggedIn","isGlobalAdmin","isEnabled","feature","loadCustomer","customer","deleteSession","reset","isWhitelabelAccount","isWhitelabel","NotFoundError","onRetryLogin","retryAsyncLogin","flashedIn","computedValue","currentStyle","getComputedOpacity","computedOpacity","flashOutElement","_webkit_touch_callout","_webkit_user_select","_khtml_user_select","_moz_user_select","_ms_user_select","user_select"],"mappings":"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"}