Compare commits

...

2 commits

Author SHA1 Message Date
d0d81510cc store: catch failure to load from API 2024-08-26 19:14:04 +00:00
af5abc7c8f major refactoring
- use bulma 1.0
- use vue composition API for several components
2024-08-26 19:09:43 +00:00
15 changed files with 235 additions and 408 deletions

View file

@ -11,7 +11,6 @@
}, },
"devDependencies": { "devDependencies": {
"@fortawesome/fontawesome-svg-core": "^6.6.0", "@fortawesome/fontawesome-svg-core": "^6.6.0",
"@fortawesome/free-brands-svg-icons": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.6.0", "@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/vue-fontawesome": "^3.0.8", "@fortawesome/vue-fontawesome": "^3.0.8",
"@types/chai": "^4.3.17", "@types/chai": "^4.3.17",
@ -26,11 +25,9 @@
"@vue/cli-service": "~5.0.0", "@vue/cli-service": "~5.0.0",
"@vue/eslint-config-typescript": "^13.0.0", "@vue/eslint-config-typescript": "^13.0.0",
"@vue/test-utils": "^2.4.6", "@vue/test-utils": "^2.4.6",
"@vueuse/core": "^10.11.1",
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"axios": "^1.7.3", "axios": "^1.7.3",
"bulma": "^0.9.4", "bulma": "^1.0.2",
"bulma-prefers-dark": "^0.1.0-beta.1",
"bulma-toast": "2.4.3", "bulma-toast": "2.4.3",
"chai": "^5.1.1", "chai": "^5.1.1",
"core-js": "^3.38.0", "core-js": "^3.38.0",

View file

@ -1,11 +1,10 @@
@charset "utf-8"; @charset "utf-8";
@use "sass:map";
//===================== //=====================
// custom color scheme // custom color scheme
//===================== //=====================
$advent22-colors: ( $colors: (
"primary": #945DE1, "primary": #945DE1,
"link": #64B4BD, "link": #64B4BD,
"info": #8C4E80, "info": #8C4E80,
@ -13,10 +12,3 @@ $advent22-colors: (
"warning": #F6CA6B, "warning": #F6CA6B,
"danger": #C5443B, "danger": #C5443B,
); );
$primary: map.get($advent22-colors, "primary");
$link: map.get($advent22-colors, "link");
$info: map.get($advent22-colors, "info");
$success: map.get($advent22-colors, "success");
$warning: map.get($advent22-colors, "warning");
$danger: map.get($advent22-colors, "danger");

View file

@ -78,14 +78,14 @@ export default class extends Vue {
private multi_modal?: MultiModal; private multi_modal?: MultiModal;
public toast?: BulmaToast; public toast?: typeof BulmaToast;
private toast_timeout?: number; private toast_timeout?: number;
public modal_handle(modal: MultiModal) { public modal_handle(modal: MultiModal) {
this.multi_modal = modal; this.multi_modal = modal;
} }
public toast_handle(toast: BulmaToast) { public toast_handle(toast: typeof BulmaToast) {
this.toast = toast; this.toast = toast;
if (this.store.is_touch_device) return; if (this.store.is_touch_device) return;

View file

@ -69,6 +69,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { Step } from "@/lib/helpers";
import { DoorSaved } from "@/lib/model"; import { DoorSaved } from "@/lib/model";
import { Door } from "@/lib/rects/door"; import { Door } from "@/lib/rects/door";
import { advent22Store } from "@/lib/store"; import { advent22Store } from "@/lib/store";
@ -78,7 +79,7 @@ import { API } from "@/lib/api";
import { APIError } from "@/lib/api_error"; import { APIError } from "@/lib/api_error";
import { toast } from "bulma-toast"; import { toast } from "bulma-toast";
import Calendar from "../Calendar.vue"; import Calendar from "../Calendar.vue";
import BulmaBreadcrumbs, { Step } from "../bulma/Breadcrumbs.vue"; import BulmaBreadcrumbs from "../bulma/Breadcrumbs.vue";
import BulmaButton from "../bulma/Button.vue"; import BulmaButton from "../bulma/Button.vue";
import BulmaDrawer from "../bulma/Drawer.vue"; import BulmaDrawer from "../bulma/Drawer.vue";
import DoorChooser from "../editor/DoorChooser.vue"; import DoorChooser from "../editor/DoorChooser.vue";

View file

@ -1,15 +1,16 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template> <template>
<nav class="breadcrumb has-succeeds-separator"> <nav class="breadcrumb has-succeeds-separator">
<ul> <ul>
<li <li
v-for="(step, index) in steps" v-for="(step, index) in steps"
:key="`step-${index}`" :key="index"
:class="modelValue === index ? 'is-active' : ''" :class="modelValue === index ? 'is-active' : ''"
@click.left="change_step(index)" @click.left="change_step(index)"
> >
<a> <a>
<span class="icon is-small"> <span class="icon is-small">
<font-awesome-icon :icon="step.icon" /> <FontAwesomeIcon :icon="step.icon" />
</span> </span>
<span>{{ step.label }}</span> <span>{{ step.label }}</span>
</a> </a>
@ -18,31 +19,21 @@
</nav> </nav>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { Options, Vue } from "vue-class-component"; import { Step } from "@/lib/helpers";
export interface Step { const props = defineProps<{
label: string; steps: Step[];
icon: string; modelValue: number;
} }>();
@Options({ const emit = defineEmits<{
props: { "update:modelValue": [number];
steps: Array, }>();
modelValue: Number,
},
emits: ["update:modelValue"],
})
export default class extends Vue {
public steps!: Step[];
public modelValue!: number;
public change_step(next_step: number) { function change_step(next_step: number) {
if (next_step === this.modelValue) { if (next_step === props.modelValue) return;
return;
}
this.$emit("update:modelValue", next_step); emit("update:modelValue", next_step);
}
} }
</script> </script>

View file

@ -1,45 +1,28 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template> <template>
<button class="button"> <button class="button">
<slot v-if="text === undefined" name="default"> <slot name="default">
<font-awesome-icon <span v-if="icon !== undefined" class="icon">
<FontAwesomeIcon
v-if="icon !== undefined" v-if="icon !== undefined"
:icon="icon" :icon="icon"
:beat-fade="busy" :beat-fade="busy"
/> />
</slot>
<template v-else>
<span v-if="icon !== undefined" class="icon">
<slot name="default">
<font-awesome-icon :icon="icon" :beat-fade="busy" />
</slot>
</span> </span>
<span>{{ text }}</span> </slot>
</template> <span v-if="text !== undefined">{{ text }}</span>
</button> </button>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { Options, Vue } from "vue-class-component"; withDefaults(
defineProps<{
@Options({ icon?: string | string[];
props: { text?: string;
icon: { busy?: boolean;
type: String, }>(),
required: false, {
busy: false,
}, },
text: { );
type: String,
required: false,
},
busy: {
type: Boolean,
default: false,
},
},
})
export default class extends Vue {
public icon?: string;
public text?: string;
public busy!: boolean;
}
</script> </script>

View file

@ -1,36 +1,37 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template> <template>
<div class="card"> <div class="card">
<header class="card-header is-unselectable" style="cursor: pointer"> <header class="card-header is-unselectable" style="cursor: pointer">
<p class="card-header-title" @click="toggle">{{ header }}</p> <p class="card-header-title" @click="toggle">{{ header }}</p>
<p v-if="refreshable" class="card-header-icon px-0"> <p v-if="refreshable" class="card-header-icon px-0">
<BulmaButton class="tag icon is-primary" @click="refresh"> <BulmaButton class="is-small is-primary" @click="refresh">
<font-awesome-icon <FontAwesomeIcon
icon="fa-solid fa-arrows-rotate" :icon="['fas', 'arrows-rotate']"
:spin="is_open && loading" :spin="is_open && state === 'loading'"
/> />
</BulmaButton> </BulmaButton>
</p> </p>
<button class="card-header-icon" @click="toggle"> <button class="card-header-icon" @click="toggle">
<span class="icon"> <span class="icon">
<font-awesome-icon <FontAwesomeIcon
:icon="'fa-solid fa-angle-' + (is_open ? 'down' : 'right')" :icon="['fas', is_open ? 'angle-down' : 'angle-right']"
/> />
</span> </span>
</button> </button>
</header> </header>
<template v-if="is_open"> <template v-if="is_open">
<div v-if="loading" class="card-content"> <div v-if="state === 'loading'" class="card-content">
<progress class="progress is-primary" max="100" /> <progress class="progress is-primary" />
</div> </div>
<div <div
v-else-if="failed" v-else-if="state === 'failed'"
class="card-content has-text-danger has-text-centered" class="card-content has-text-danger has-text-centered"
> >
<span class="icon is-large"> <span class="icon is-large">
<font-awesome-icon icon="fa-solid fa-ban" size="3x" /> <FontAwesomeIcon :icon="['fas', 'ban']" size="3x" />
</span> </span>
</div> </div>
<slot v-else name="default" /> <slot v-else name="default" />
@ -38,63 +39,46 @@
</div> </div>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { Options, Vue } from "vue-class-component"; import { ref } from "vue";
import BulmaButton from "./Button.vue"; import BulmaButton from "./Button.vue";
enum DrawerState { withDefaults(
Loading, defineProps<{
Ready, header: string;
Failed, refreshable?: boolean;
} }>(),
{ refreshable: false },
@Options({
components: {
BulmaButton,
},
props: {
header: String,
refreshable: {
type: Boolean,
default: false,
},
},
emits: ["open"],
})
export default class extends Vue {
public header!: string;
public refreshable!: boolean;
public is_open = false;
public state = DrawerState.Loading;
public toggle() {
this.is_open = !this.is_open;
if (this.is_open) {
this.state = DrawerState.Loading;
this.$emit(
"open",
() => (this.state = DrawerState.Ready),
() => (this.state = DrawerState.Failed),
); );
const emit = defineEmits<{
open: [
{
ready(): void;
fail(): void;
},
];
}>();
const is_open = ref(false);
const state = ref<"loading" | "ready" | "failed">("loading");
function toggle() {
is_open.value = !is_open.value;
if (is_open.value) {
state.value = "loading";
emit("open", {
ready: () => (state.value = "ready"),
fail: () => (state.value = "failed"),
});
} }
} }
public refresh() { function refresh() {
this.is_open = false; is_open.value = false;
this.toggle(); toggle();
}
public get loading(): boolean {
return this.state === DrawerState.Loading;
}
public get failed(): boolean {
return this.state === DrawerState.Failed;
}
} }
</script> </script>

View file

@ -1,68 +1,47 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template> <template>
<slot v-if="show" name="default" /> <slot v-if="state === 'show'" name="default" />
<span v-else>***</span> <span v-else>***</span>
<BulmaButton <BulmaButton
:class="`tag icon is-${button_class} ml-2`" :class="`is-small is-${button_class} ml-2`"
:icon="`fa-solid fa-${button_icon}`" :icon="['fas', `${button_icon}`]"
:busy="busy" :busy="state === 'click'"
@click="on_click" @click="on_click"
/> />
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { Options, Vue } from "vue-class-component"; import { ref } from "vue";
import BulmaButton from "./Button.vue"; import BulmaButton from "./Button.vue";
enum ClickState { const emit = defineEmits<{
Green = 0, load: [];
Yellow = 1, }>();
Red = 2,
}
@Options({ const state = ref<"start" | "click" | "show">("start");
components: { const button_class = ref<"primary" | "warning" | "danger">("primary");
BulmaButton, const button_icon = ref<"eye-slash" | "eye">("eye-slash");
},
emits: ["load"],
})
export default class extends Vue {
public state = ClickState.Green;
public on_click(): void { function on_click(): void {
this.state++; switch (state.value) {
this.state %= 3; case "show":
state.value = "start";
button_class.value = "primary";
button_icon.value = "eye-slash";
break;
if (this.state === ClickState.Red) { case "start":
this.$emit("load"); state.value = "click";
} button_class.value = "warning";
} button_icon.value = "eye-slash";
break;
public get show(): boolean { case "click":
return this.state === ClickState.Red; state.value = "show";
} button_class.value = "danger";
button_icon.value = "eye";
public get busy(): boolean { emit("load");
return this.state === ClickState.Yellow; break;
}
public get button_class(): string {
switch (this.state) {
case ClickState.Red:
return "danger";
case ClickState.Yellow:
return "warning";
default:
return "primary";
}
}
public get button_icon(): string {
if (this.state === ClickState.Red) {
return "eye-slash";
} else {
return "eye";
}
} }
} }
</script> </script>

View file

@ -1,3 +1,4 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template> <template>
<div style="display: none"> <div style="display: none">
<div v-bind="$attrs" ref="message"> <div v-bind="$attrs" ref="message">
@ -6,38 +7,43 @@
</div> </div>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import * as bulmaToast from "bulma-toast"; import * as bulmaToast from "bulma-toast";
import { Options, Vue } from "vue-class-component"; import { onMounted, ref } from "vue";
@Options({ const emit = defineEmits<{
emits: ["handle"], handle: [
}) {
export default class extends Vue { show(options: bulmaToast.Options): void;
public created(): void { hide(): void;
this.$emit("handle", this); },
} ];
}>();
public show(options: bulmaToast.Options = {}) { const message = ref<HTMLDivElement | null>(null);
if (!(this.$refs.message instanceof HTMLElement)) return;
onMounted(() =>
emit("handle", {
show(options: bulmaToast.Options = {}) {
if (!(message.value instanceof HTMLElement)) return;
bulmaToast.toast({ bulmaToast.toast({
...options, ...options,
single: true, single: true,
message: this.$refs.message, message: message.value,
}); });
} },
hide() {
if (!(message.value instanceof HTMLElement)) return;
public hide() { const toast_div = message.value.parentElement;
if (!(this.$refs.message instanceof HTMLElement)) return;
const toast_div = this.$refs.message.parentElement;
if (!(toast_div instanceof HTMLDivElement)) return; if (!(toast_div instanceof HTMLDivElement)) return;
const dbutton = toast_div.querySelector("button.delete"); const dbutton = toast_div.querySelector("button.delete");
if (!(dbutton instanceof HTMLButtonElement)) return; if (!(dbutton instanceof HTMLButtonElement)) return;
dbutton.click(); dbutton.click();
} },
} }),
);
</script> </script>

View file

@ -1,27 +1,30 @@
<template> <template>
<foreignObject <foreignObject
:x="Math.round(aspect_ratio * rectangle.left)" :x="Math.round(get_bg_aspect_ratio() * rectangle.left)"
:y="rectangle.top" :y="rectangle.top"
:width="Math.round(aspect_ratio * rectangle.width)" :width="Math.round(get_bg_aspect_ratio() * rectangle.width)"
:height="rectangle.height" :height="rectangle.height"
:style="`transform: scaleX(${1 / aspect_ratio})`" :style="`transform: scaleX(${1 / get_bg_aspect_ratio()})`"
> >
<div <div
xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"
:class="`px-2 is-flex is-align-items-center is-justify-content-center is-size-2 has-text-weight-bold ${extra_classes}`" :class="`px-2 is-flex is-align-items-center is-justify-content-center is-size-2 has-text-weight-bold ${variant} ${
visible ? 'visible' : ''
}`"
style="height: inherit" style="height: inherit"
:title="title" v-bind="$attrs"
> >
<slot name="default" /> <slot name="default" />
</div> </div>
</foreignObject> </foreignObject>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { loading_success } from "@/lib/helpers"; import { loading_success } from "@/lib/helpers";
import { Rectangle } from "@/lib/rects/rectangle"; import { Rectangle } from "@/lib/rects/rectangle";
import { advent22Store } from "@/lib/store"; import { advent22Store } from "@/lib/store";
import { Options, Vue } from "vue-class-component";
const store = advent22Store();
type BulmaVariant = type BulmaVariant =
| "primary" | "primary"
@ -31,48 +34,26 @@ type BulmaVariant =
| "warning" | "warning"
| "danger"; | "danger";
@Options({ withDefaults(
props: { defineProps<{
variant: String, variant: BulmaVariant;
visible: { visible?: boolean;
type: Boolean, rectangle: Rectangle;
default: false, }>(),
{
visible: true,
}, },
rectangle: Rectangle,
title: {
type: String,
required: false,
},
},
})
export default class extends Vue {
public readonly store = advent22Store();
private variant!: BulmaVariant;
private visible!: boolean;
public rectangle!: Rectangle;
public title?: string;
public get extra_classes(): string {
let result = this.variant;
if (this.visible) result += " visible";
return result;
}
public get aspect_ratio(): number {
if (!loading_success(this.store.background_image)) return 1;
return (
this.store.background_image.height / this.store.background_image.width
); );
}
function get_bg_aspect_ratio(): number {
if (!loading_success(store.background_image)) return 1;
return store.background_image.height / store.background_image.width;
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "@/bulma-scheme"; @use "@/bulma-scheme" as scheme;
foreignObject > div { foreignObject > div {
&:not(.visible, :hover):deep() > * { &:not(.visible, :hover):deep() > * {
@ -84,7 +65,7 @@ foreignObject > div {
border-width: 2px; border-width: 2px;
border-style: solid; border-style: solid;
@each $name, $color in $advent22-colors { @each $name, $color in scheme.$colors {
&.#{$name} { &.#{$name} {
background-color: rgba($color, 0.3); background-color: rgba($color, 0.3);
border-color: rgba($color, 0.9); border-color: rgba($color, 0.9);

View file

@ -15,10 +15,8 @@
</svg> </svg>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { Vector2D } from "@/lib/rects/vector2d"; import { Vector2D } from "@/lib/rects/vector2d";
import { advent22Store } from "@/lib/store";
import { Options, Vue } from "vue-class-component";
function get_event_thous(event: MouseEvent): Vector2D { function get_event_thous(event: MouseEvent): Vector2D {
if (!(event.currentTarget instanceof SVGSVGElement)) { if (!(event.currentTarget instanceof SVGSVGElement)) {
@ -31,36 +29,22 @@ function get_event_thous(event: MouseEvent): Vector2D {
); );
} }
function mouse_event_validator(event: object, point: object): boolean { type TCMouseEvent = [MouseEvent, Vector2D];
if (!(event instanceof MouseEvent)) {
console.warn(event, "is not a MouseEvent!");
return false;
}
if (!(point instanceof Vector2D)) { const emit = defineEmits<{
console.warn(point, "is not a Vector2D!"); mousedown: TCMouseEvent;
return false; mouseup: TCMouseEvent;
} mousemove: TCMouseEvent;
click: TCMouseEvent;
dblclick: TCMouseEvent;
}>();
return true; function transform_mouse_event(event: MouseEvent) {
}
@Options({
emits: {
mousedown: mouse_event_validator,
mouseup: mouse_event_validator,
mousemove: mouse_event_validator,
click: mouse_event_validator,
dblclick: mouse_event_validator,
},
})
export default class extends Vue {
public readonly store = advent22Store();
public transform_mouse_event(event: MouseEvent) {
const point = get_event_thous(event); const point = get_event_thous(event);
this.$emit(event.type, event, point);
} // mute a useless typescript error
const event_type = event.type as "mousedown";
emit(event_type, event, point);
} }
</script> </script>

View file

@ -37,3 +37,8 @@ export function handle_error(error: unknown) {
export function name_door(day: number): string { export function name_door(day: number): string {
return `Türchen ${day}`; return `Türchen ${day}`;
} }
export interface Step {
label: string;
icon: string | string[];
}

View file

@ -67,6 +67,7 @@ export const advent22Store = defineStore({
document.getElementsByTagName("head")[0].appendChild(link); document.getElementsByTagName("head")[0].appendChild(link);
} catch {} } catch {}
try {
const [is_admin, site_config, background_image, user_doors, next_door] = const [is_admin, site_config, background_image, user_doors, next_door] =
await Promise.all([ await Promise.all([
this.update_is_admin(), this.update_is_admin(),
@ -91,6 +92,9 @@ export const advent22Store = defineStore({
} }
if (next_door !== null) this.next_door_target = Date.now() + next_door; if (next_door !== null) this.next_door_target = Date.now() + next_door;
} catch {
this.background_image = "error";
}
}, },
when_initialized(callback: () => void): void { when_initialized(callback: () => void): void {

View file

@ -1,64 +1,23 @@
@charset "utf-8"; @charset "utf-8";
@use "sass:map";
//=========== //==============
// variables // bulma
//=========== //==============
// custom color scheme // custom color scheme
@import "@/bulma-scheme"; @use "bulma-scheme" as scheme;
@use "bulma/sass" with (
// Sass variables (bulma) $primary: map.get(scheme.$colors, "primary"),
@import "~bulma/sass/utilities/initial-variables.sass"; $link: map.get(scheme.$colors, "link"),
@import "~bulma/sass/utilities/derived-variables.sass"; $info: map.get(scheme.$colors, "info"),
$success: map.get(scheme.$colors, "success"),
// Sass variables (bulma-prefers-dark) $warning: map.get(scheme.$colors, "warning"),
@import "~bulma-prefers-dark/sass/utilities/initial-variables.sass"; $danger: map.get(scheme.$colors, "danger")
@import "~bulma-prefers-dark/sass/utilities/derived-variables.sass"; );
//=================
// variable tweaks
//=================
$modal-card-body-background-color-dark: $body-background-dark;
$card-background-color-dark: $background-dark;
//============== //==============
// main imports // main imports
//============== //==============
@import "~animate.css/animate"; @import "animate.css/animate";
@import "~bulma/bulma";
@import "~bulma-prefers-dark/bulma-prefers-dark";
//==============
// style tweaks
//==============
.card-header {
background-color: $background;
@include prefers-scheme(dark) {
background-color: $card-header-background-color;
}
}
.card-content {
@include prefers-scheme(dark) {
background-color: $body-background-dark;
}
}
.progress {
// &::-webkit-progress-bar {
// background-color: transparent !important;
// }
// &::-webkit-progress-value {
// background-color: transparent !important;
// }
&::-moz-progress-bar {
background-color: transparent !important;
}
// &::-ms-fill {
// background-color: transparent !important;
// }
}

View file

@ -1084,13 +1084,6 @@
dependencies: dependencies:
"@fortawesome/fontawesome-common-types" "6.6.0" "@fortawesome/fontawesome-common-types" "6.6.0"
"@fortawesome/free-brands-svg-icons@^6.6.0":
version "6.6.0"
resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz#2797f2cc66d21e7e47fa64e680b8835e8d30e825"
integrity sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ==
dependencies:
"@fortawesome/fontawesome-common-types" "6.6.0"
"@fortawesome/free-solid-svg-icons@^6.6.0": "@fortawesome/free-solid-svg-icons@^6.6.0":
version "6.6.0" version "6.6.0"
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz#061751ca43be4c4d814f0adbda8f006164ec9f3b" resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz#061751ca43be4c4d814f0adbda8f006164ec9f3b"
@ -1492,11 +1485,6 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/web-bluetooth@^0.0.20":
version "0.0.20"
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597"
integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==
"@types/webpack-env@^1.15.2": "@types/webpack-env@^1.15.2":
version "1.18.4" version "1.18.4"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.4.tgz#62879b0a9c653f9b1172d403b882f2045ecce032" resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.4.tgz#62879b0a9c653f9b1172d403b882f2045ecce032"
@ -2006,28 +1994,6 @@
resolved "https://registry.yarnpkg.com/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz#b6b40a7625429d2bd7c2281ddba601ed05dc7f1a" resolved "https://registry.yarnpkg.com/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz#b6b40a7625429d2bd7c2281ddba601ed05dc7f1a"
integrity sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA== integrity sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==
"@vueuse/core@^10.11.1":
version "10.11.1"
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.11.1.tgz#15d2c0b6448d2212235b23a7ba29c27173e0c2c6"
integrity sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==
dependencies:
"@types/web-bluetooth" "^0.0.20"
"@vueuse/metadata" "10.11.1"
"@vueuse/shared" "10.11.1"
vue-demi ">=0.14.8"
"@vueuse/metadata@10.11.1":
version "10.11.1"
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.11.1.tgz#209db7bb5915aa172a87510b6de2ca01cadbd2a7"
integrity sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==
"@vueuse/shared@10.11.1":
version "10.11.1"
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.11.1.tgz#62b84e3118ae6e1f3ff38f4fbe71b0c5d0f10938"
integrity sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==
dependencies:
vue-demi ">=0.14.8"
"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": "@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5":
version "1.11.6" version "1.11.6"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24"
@ -2574,20 +2540,15 @@ buffer@^5.5.0:
base64-js "^1.3.1" base64-js "^1.3.1"
ieee754 "^1.1.13" ieee754 "^1.1.13"
bulma-prefers-dark@^0.1.0-beta.1:
version "0.1.0-beta.1"
resolved "https://registry.yarnpkg.com/bulma-prefers-dark/-/bulma-prefers-dark-0.1.0-beta.1.tgz#074aa71899f389a0137dd3753f0d89e96ab1e59b"
integrity sha512-ti4sKxIIrTAvGtsYc9Rk66SUZSH/j63EU1hApQijQVlKFF0qBLGSb8E16HhI83KJaIeYP4aAHQv2tj0ara831A==
bulma-toast@2.4.3: bulma-toast@2.4.3:
version "2.4.3" version "2.4.3"
resolved "https://registry.yarnpkg.com/bulma-toast/-/bulma-toast-2.4.3.tgz#cd302ad5ed625f47d7426b48b741250950e1cbf9" resolved "https://registry.yarnpkg.com/bulma-toast/-/bulma-toast-2.4.3.tgz#cd302ad5ed625f47d7426b48b741250950e1cbf9"
integrity sha512-OpNn3MUD27ne8RkQns3yS7HaltU5/s67ivbdxAb/gXjxmfZhIdoeUFPYkopEXwCpzc+VasYy1OAglGIFvjEvUQ== integrity sha512-OpNn3MUD27ne8RkQns3yS7HaltU5/s67ivbdxAb/gXjxmfZhIdoeUFPYkopEXwCpzc+VasYy1OAglGIFvjEvUQ==
bulma@^0.9.4: bulma@^1.0.2:
version "0.9.4" version "1.0.2"
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.9.4.tgz#0ca8aeb1847a34264768dba26a064c8be72674a1" resolved "https://registry.yarnpkg.com/bulma/-/bulma-1.0.2.tgz#47395a660755c9566db3cf981fd4e3a2b637af19"
integrity sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ== integrity sha512-D7GnDuF6seb6HkcnRMM9E739QpEY9chDzzeFrHMyEns/EXyDJuQ0XA0KxbBl/B2NTsKSoDomW61jFGFaAxhK5A==
bytes@3.0.0: bytes@3.0.0:
version "3.0.0" version "3.0.0"
@ -7079,7 +7040,7 @@ vue-component-type-helpers@^2.0.0:
resolved "https://registry.yarnpkg.com/vue-component-type-helpers/-/vue-component-type-helpers-2.0.7.tgz#f142e82440da61fa81671ac2f35fd87146248897" resolved "https://registry.yarnpkg.com/vue-component-type-helpers/-/vue-component-type-helpers-2.0.7.tgz#f142e82440da61fa81671ac2f35fd87146248897"
integrity sha512-7e12Evdll7JcTIocojgnCgwocX4WzIYStGClBQ+QuWPinZo/vQolv2EMq4a3lg16TKfwWafLimG77bxb56UauA== integrity sha512-7e12Evdll7JcTIocojgnCgwocX4WzIYStGClBQ+QuWPinZo/vQolv2EMq4a3lg16TKfwWafLimG77bxb56UauA==
vue-demi@>=0.14.8, vue-demi@^0.14.10: vue-demi@^0.14.10:
version "0.14.10" version "0.14.10"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.10.tgz#afc78de3d6f9e11bf78c55e8510ee12814522f04" resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.10.tgz#afc78de3d6f9e11bf78c55e8510ee12814522f04"
integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg== integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==