feat: add vite-svg-loader and add Logo component (#971)

Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/971
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
This commit is contained in:
dpschen 2021-11-13 14:16:14 +00:00 committed by konrad
parent 8e6e52bf02
commit 30cc89fe25
22 changed files with 335 additions and 238 deletions

View file

@ -7,7 +7,7 @@ describe('The Menu', () => {
}) })
it('Can be hidden on desktop', () => { it('Can be hidden on desktop', () => {
cy.get('a.menu-show-button:visible') cy.get('button.menu-show-button:visible')
.click() .click()
cy.get('.namespace-container') cy.get('.namespace-container')
.should('not.have.class', 'is-active') .should('not.have.class', 'is-active')
@ -21,7 +21,7 @@ describe('The Menu', () => {
it('Is can be shown on mobile', () => { it('Is can be shown on mobile', () => {
cy.viewport('iphone-8') cy.viewport('iphone-8')
cy.get('a.menu-show-button:visible') cy.get('button.menu-show-button:visible')
.click() .click()
cy.get('.namespace-container') cy.get('.namespace-container')
.should('have.class', 'is-active') .should('have.class', 'is-active')

View file

@ -81,6 +81,7 @@
"vite": "2.6.14", "vite": "2.6.14",
"vite-plugin-pwa": "0.11.3", "vite-plugin-pwa": "0.11.3",
"vue-tsc": "0.29.4", "vue-tsc": "0.29.4",
"vite-svg-loader": "^3.1.0",
"wait-on": "6.0.0", "wait-on": "6.0.0",
"workbox-cli": "6.3.0" "workbox-cli": "6.3.0"
}, },

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -0,0 +1,11 @@
<script setup lang="ts">
import { computed } from 'vue'
import LogoFull from '@/assets/logo-full.svg?component'
import LogoFullPride from '@/assets/logo-full-pride.svg?component'
const Logo = computed(() => new Date().getMonth() === 5 ? LogoFullPride : LogoFull)
</script>
<template>
<Logo alt="Vikunja" />
</template>

View file

@ -0,0 +1,75 @@
<template>
<button
type="button"
@click="$store.commit('toggleMenu')"
class="menu-show-button"
@shortkey="() => $store.commit('toggleMenu')"
v-shortkey="['ctrl', 'e']"
:aria-label="menuActive ? $t('misc.hideMenu') : $t('misc.showMenu')"
/>
</template>
<script setup>
import { computed} from 'vue'
import {store} from '@/store'
const menuActive = computed(() => store.menuActive)
</script>
<style lang="scss" scoped>
$lineWidth: 2rem;
$size: $lineWidth + 1rem;
.menu-show-button {
// FIXME: create general button component
appearance: none;
background-color: transparent;
border: 0;
min-height: $size;
width: $size;
position: relative;
$transformX: translateX(-50%);
&::before,
&::after {
content: '';
display: block;
position: absolute;
height: 3px;
width: $lineWidth;
left: 50%;
transform: $transformX;
background-color: $grey-400;
border-radius: 2px;
transition: all $transition;
}
&::before {
top: 50%;
transform: $transformX translateY(-0.4rem)
}
&::after {
bottom: 50%;
transform: $transformX translateY(0.4rem)
}
&:hover,
&:focus {
&::before,
&::after {
background-color: $grey-600;
}
&::before {
transform: $transformX translateY(-0.5rem);
}
&::after {
transform: $transformX translateY(0.5rem)
}
}
}
</style>

View file

@ -0,0 +1,20 @@
<template>
<a class="menu-bottom-link" :href="poweredByUrl" target="_blank" rel="noreferrer noopener nofollow">
{{ $t('misc.poweredBy') }}
</a>
</template>
<script setup lang="ts">
import {POWERED_BY as poweredByUrl} from '@/urls'
</script>
<style lang="scss">
.menu-bottom-link {
color: $grey-300;
text-align: center;
display: block;
padding-top: 1rem;
padding-bottom: 1rem;
font-size: .8rem;
}
</style>

View file

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<a @click="$store.commit('menuActive', false)" class="menu-hide-button" v-if="menuActive"> <a @click="$store.commit('menuActive', false)" class="menu-hide-button" v-if="menuActive">
<icon icon="times"></icon> <icon icon="times" />
</a> </a>
<div <div
:class="{'has-background': background}" :class="{'has-background': background}"
@ -134,6 +134,32 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.menu-hide-button {
position: fixed;
top: 0.5rem;
right: 0.5rem;
z-index: 31;
width: 3rem;
height: 3rem;
display: flex;
justify-content: center;
align-items: center;
font-size: 2rem;
color: $grey-400;
line-height: 1;
transition: all $transition;
@media screen and (min-width: $tablet) {
display: none;
}
&:hover,
&:focus {
height: 1rem;
color: $grey-600;
}
}
.app-container { .app-container {
min-height: calc(100vh - 65px); min-height: calc(100vh - 65px);

View file

@ -6,7 +6,7 @@
> >
<div class="container has-text-centered link-share-view"> <div class="container has-text-centered link-share-view">
<div class="column is-10 is-offset-1"> <div class="column is-10 is-offset-1">
<img alt="Vikunja" class="logo" :src="logoUrl" /> <Logo class="logo" />
<h1 <h1
:style="{ 'opacity': currentList.title === '' ? '0': '1' }" :style="{ 'opacity': currentList.title === '' ? '0': '1' }"
class="title"> class="title">
@ -14,9 +14,7 @@
</h1> </h1>
<div class="box has-text-left view"> <div class="box has-text-left view">
<router-view/> <router-view/>
<a class="menu-bottom-link" href="https://vikunja.io" target="_blank" rel="noreferrer noopener nofollow"> <PoweredByLink />
{{ $t('misc.poweredBy') }}
</a>
</div> </div>
</div> </div>
</div> </div>
@ -25,51 +23,45 @@
<script> <script>
import {mapState} from 'vuex' import {mapState} from 'vuex'
import {CURRENT_LIST} from '@/store/mutation-types'
import logoUrl from '@/assets/logo-full.svg' import Logo from '@/components/home/Logo.vue'
import PoweredByLink from './PoweredByLink.vue'
export default { export default {
name: 'contentLinkShare', name: 'contentLinkShare',
data() { components: {
return { Logo,
logoUrl, PoweredByLink,
}
}, },
computed: mapState({ computed: mapState([
currentList: CURRENT_LIST, 'currentList',
background: 'background', 'background',
}), ]),
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.link-share-container.has-background .view { .link-share-container.has-background .view {
background: transparent; background-color: transparent;
border: none; border: none;
.logout .button {
box-shadow: none;
}
} }
.link-share-view { .logo {
.logo {
max-width: 300px; max-width: 300px;
width: 90%; width: 90%;
margin: 2rem 0 1.5rem; margin: 2rem 0 1.5rem;
} }
.column { .column {
max-width: 100%; max-width: 100%;
} }
.card { .title {
background: $white;
}
.title {
text-shadow: 0 0 1rem $white; text-shadow: 0 0 1rem $white;
} }
// FIXME: this should be defined somewhere deep
.link-share-view .card {
background-color: $white;
} }
</style> </style>

View file

@ -1,7 +1,7 @@
<template> <template>
<div class="no-auth-wrapper"> <div class="no-auth-wrapper">
<div class="noauth-container"> <div class="noauth-container">
<img alt="Vikunja" :src="logoUrl" width="400" height="117" /> <Logo width="400" height="117" />
<div class="message is-info" v-if="motd !== ''"> <div class="message is-info" v-if="motd !== ''">
<div class="message-header"> <div class="message-header">
<p>{{ $t('misc.info') }}</p> <p>{{ $t('misc.info') }}</p>
@ -18,16 +18,13 @@
<script> <script>
import {mapState} from 'vuex' import {mapState} from 'vuex'
import logoUrl from '@/assets/logo-full.svg' import Logo from '@/components/home/Logo.vue'
import { saveLastVisited } from '@/helpers/saveLastVisited' import { saveLastVisited } from '@/helpers/saveLastVisited'
export default { export default {
name: 'contentNoAuth', name: 'contentNoAuth',
data() { components: { Logo },
return {
logoUrl,
}
},
computed: { computed: {
routeName() { routeName() {
return this.$route.name return this.$route.name
@ -68,7 +65,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.no-auth-wrapper { .no-auth-wrapper {
background: url('@/assets/llama.svg') no-repeat bottom left fixed $light-background; background: url('@/assets/llama.svg?url') no-repeat bottom left fixed $light-background;
min-height: 100vh; min-height: 100vh;
} }

View file

@ -2,7 +2,7 @@
<div :class="{'is-active': menuActive}" class="namespace-container"> <div :class="{'is-active': menuActive}" class="namespace-container">
<div class="menu top-menu"> <div class="menu top-menu">
<router-link :to="{name: 'home'}" class="logo"> <router-link :to="{name: 'home'}" class="logo">
<img alt="Vikunja" :src="logoUrl" width="164" height="48"/> <Logo width="164" height="48" />
</router-link> </router-link>
<ul class="menu-list"> <ul class="menu-list">
<li> <li>
@ -146,25 +146,34 @@
</div> </div>
</template> </template>
</aside> </aside>
<a class="menu-bottom-link" :href="poweredByUrl" target="_blank" rel="noreferrer noopener nofollow"> <PoweredByLink />
{{ $t('misc.poweredBy') }}
</a>
</div> </div>
</template> </template>
<script> <script>
import {mapState} from 'vuex' import {mapState} from 'vuex'
import {CURRENT_LIST, MENU_ACTIVE, LOADING, LOADING_MODULE} from '@/store/mutation-types' import draggable from 'vuedraggable'
import ListSettingsDropdown from '@/components/list/list-settings-dropdown.vue' import ListSettingsDropdown from '@/components/list/list-settings-dropdown.vue'
import NamespaceSettingsDropdown from '@/components/namespace/namespace-settings-dropdown.vue' import NamespaceSettingsDropdown from '@/components/namespace/namespace-settings-dropdown.vue'
import draggable from 'vuedraggable' import PoweredByLink from '@/components/home/PoweredByLink.vue'
import {calculateItemPosition} from '@/helpers/calculateItemPosition' import Logo from '@/components/home/Logo.vue'
import {POWERED_BY} from '@/urls'
import {CURRENT_LIST, MENU_ACTIVE, LOADING, LOADING_MODULE} from '@/store/mutation-types'
import {calculateItemPosition} from '@/helpers/calculateItemPosition'
import logoUrl from '@/assets/logo-full.svg'
export default { export default {
name: 'navigation', name: 'navigation',
components: {
ListSettingsDropdown,
NamespaceSettingsDropdown,
draggable,
Logo,
PoweredByLink,
},
data() { data() {
return { return {
listsVisible: {}, listsVisible: {},
@ -174,15 +183,8 @@ export default {
ghostClass: 'ghost', ghostClass: 'ghost',
}, },
listUpdating: {}, listUpdating: {},
logoUrl,
poweredByUrl: POWERED_BY,
} }
}, },
components: {
ListSettingsDropdown,
NamespaceSettingsDropdown,
draggable,
},
computed: { computed: {
...mapState({ ...mapState({
namespaces: state => state.namespaces.namespaces.filter(n => !n.isArchived), namespaces: state => state.namespaces.namespaces.filter(n => !n.isArchived),
@ -517,10 +519,13 @@ $vikunja-nav-selected-width: 0.4rem;
} }
.logo { .logo {
display: none;
@media screen and (max-width: $tablet) {
display: block; display: block;
padding-left: 2rem;
margin-right: 1rem;
@media screen and (min-width: $tablet) {
display: none;
} }
} }

View file

@ -5,24 +5,11 @@
class="navbar main-theme is-fixed-top" class="navbar main-theme is-fixed-top"
role="navigation" role="navigation"
> >
<div class="navbar-brand"> <router-link :to="{name: 'home'}" class="logo">
<router-link :to="{name: 'home'}" class="navbar-item logo"> <Logo width="164" height="48" />
<img width="164" height="48" alt="Vikunja" :src="logoUrl" />
</router-link> </router-link>
<a <MenuButton class="menu-button" />
@click="$store.commit('toggleMenu')" <div class="list-title" ref="listTitle" v-show="currentList.id">
class="menu-show-button"
@shortkey="() => $store.commit('toggleMenu')"
v-shortkey="['ctrl', 'e']"
>
</a>
</div>
<a
@click="$store.commit('toggleMenu')"
class="menu-show-button"
>
</a>
<div class="list-title" ref="listTitle" :style="{'display': currentList.id ? '': 'none'}">
<template v-if="currentList.id"> <template v-if="currentList.id">
<h1 <h1
:style="{ 'opacity': currentList.title === '' ? '0': '1' }" :style="{ 'opacity': currentList.title === '' ? '0': '1' }"
@ -101,9 +88,8 @@ import Update from '@/components/home/update.vue'
import ListSettingsDropdown from '@/components/list/list-settings-dropdown.vue' import ListSettingsDropdown from '@/components/list/list-settings-dropdown.vue'
import Dropdown from '@/components/misc/dropdown.vue' import Dropdown from '@/components/misc/dropdown.vue'
import Notifications from '@/components/notifications/notifications.vue' import Notifications from '@/components/notifications/notifications.vue'
import Logo from '@/components/home/Logo.vue'
import logoUrl from '@/assets/logo-full.svg' import MenuButton from '@/components/home/MenuButton.vue'
import logoFullPrideUrl from '@/assets/logo-full-pride.svg'
export default { export default {
name: 'topNavigation', name: 'topNavigation',
@ -112,11 +98,10 @@ export default {
Dropdown, Dropdown,
ListSettingsDropdown, ListSettingsDropdown,
Update, Update,
Logo,
MenuButton,
}, },
computed: { computed: {
logoUrl() {
return (new Date()).getMonth() === 5 ? logoFullPrideUrl : logoUrl
},
...mapState({ ...mapState({
userInfo: state => state.auth.info, userInfo: state => state.auth.info,
userAvatar: state => state.auth.avatarUrl, userAvatar: state => state.auth.avatarUrl,
@ -155,19 +140,26 @@ $vikunja-nav-logo-full-width: 164px;
.navbar { .navbar {
z-index: 4 !important; z-index: 4 !important;
}
.navbar-brand { .logo {
display: none;
@media screen and (min-width: $tablet) {
align-self: stretch;
display: flex; display: flex;
align-items: center; align-items: center;
padding-left: 2rem;
margin-right: 1.5rem;
}
}
.menu-button {
align-self: stretch;
margin-right: auto;
.logo img {
width: $vikunja-nav-logo-full-width;
}
}
&.is-dark .navbar-brand > .navbar-item {
@media screen and (max-width: $tablet) { @media screen and (max-width: $tablet) {
margin: 0 auto; margin-left: $hamburger-menu-icon-spacing;
}
} }
} }
@ -197,10 +189,6 @@ $vikunja-nav-logo-full-width: 164px;
} }
@media screen and (max-width: $tablet) { @media screen and (max-width: $tablet) {
.navbar-brand {
display: none;
}
.user { .user {
width: $user-dropdown-width-mobile; width: $user-dropdown-width-mobile;
display: flex; display: flex;

View file

@ -449,7 +449,9 @@
"saved": "Saved!", "saved": "Saved!",
"default": "Default", "default": "Default",
"close": "Close", "close": "Close",
"download": "Download" "download": "Download",
"showMenu": "Show the menu",
"hideMenu": "Hide the menu"
}, },
"input": { "input": {
"resetColor": "Reset Color", "resetColor": "Reset Color",

View file

@ -7,5 +7,4 @@
@import "form"; @import "form";
@import "link-share"; @import "link-share";
@import "loading"; @import "loading";
@import "navigation";
@import "notification"; @import "notification";

View file

@ -1,92 +0,0 @@
// FIXME: create <MenuButton> component
.menu-hide-button,
.menu-show-button {
display: none;
z-index: 31;
font-weight: bold;
font-size: 2rem;
color: $grey-400;
line-height: 1;
transition: all $transition;
&:hover,
&:focus {
height: 1rem;
color: $grey-600;
}
}
.menu-show-button {
height: .75rem;
width: 2rem;
@media screen and (max-width: $tablet) {
display: block;
margin-left: $hamburger-menu-icon-spacing;
}
// menu line icon and animationanimation // START
&::before,
&::after {
display: block;
content: '';
border-top: 3px solid $grey-400;
border-radius: $radius;
transition: all $transition;
}
&::before {
margin-bottom: .5rem;
}
&::after {
margin-top: .5rem;
}
&:hover,
&:focus {
&::before {
margin-bottom: .75rem;
}
&::after {
margin-top: .75rem;
}
}
// menu line animation // END
}
.menu-hide-button {
position: fixed;
@media screen and (max-width: $tablet) {
display: block;
top: $hamburger-menu-icon-spacing;
right: $hamburger-menu-icon-spacing;
}
&:hover,
&:focus {
color: $text;
}
}
.navbar-brand .menu-show-button {
display: block;
}
@media screen and (max-width: $tablet) {
.navbar.is-dark .navbar-brand > .navbar-item {
margin: 0 auto;
}
}
.menu-bottom-link {
width: 100%;
color: $grey-300;
text-align: center;
display: block;
margin: 1rem 0;
font-size: .8rem;
}

View file

@ -33,15 +33,6 @@ h6 {
font-weight: 400 !important; font-weight: 400 !important;
} }
.logo {
padding-left: 2rem !important;
img {
max-height: 3rem !important;
margin-right: 1rem;
}
}
// FIXME: create <ProgressBar> component. used in // FIXME: create <ProgressBar> component. used in
// - attachments.vue // - attachments.vue
// - kanban-card.vue // - kanban-card.vue

1
src/types/vite-svg-loader.d.ts vendored Normal file
View file

@ -0,0 +1 @@
/// <reference types="vite-svg-loader" />

View file

@ -41,7 +41,7 @@
<div class="progress-dots"> <div class="progress-dots">
<span v-for="i in progressDotsCount" :key="i" /> <span v-for="i in progressDotsCount" :key="i" />
</div> </div>
<img alt="Vikunja" :src="logoUrl" /> <Logo alt="Vikunja" />
</div> </div>
<p>{{ $t('migrate.inProgress') }}</p> <p>{{ $t('migrate.inProgress') }}</p>
</div> </div>
@ -70,14 +70,17 @@
<script> <script>
import AbstractMigrationService from '@/services/migrator/abstractMigration' import AbstractMigrationService from '@/services/migrator/abstractMigration'
import AbstractMigrationFileService from '@/services/migrator/abstractMigrationFile' import AbstractMigrationFileService from '@/services/migrator/abstractMigrationFile'
import {MIGRATORS} from './migrators' import Logo from '@/assets/logo.svg?component'
import logoUrl from '@/assets/logo.svg' import {MIGRATORS} from './migrators'
const PROGRESS_DOTS_COUNT = 8 const PROGRESS_DOTS_COUNT = 8
export default { export default {
name: 'MigrateService', name: 'MigrateService',
components: { Logo },
data() { data() {
return { return {
progressDotsCount: PROGRESS_DOTS_COUNT, progressDotsCount: PROGRESS_DOTS_COUNT,
@ -87,7 +90,6 @@ export default {
message: '', message: '',
migratorAuthCode: '', migratorAuthCode: '',
migrationService: null, migrationService: null,
logoUrl,
} }
}, },

View file

@ -1,8 +1,8 @@
import wunderlistIcon from './icons/wunderlist.jpg' import wunderlistIcon from './icons/wunderlist.jpg'
import todoistIcon from './icons/todoist.svg' import todoistIcon from './icons/todoist.svg?url'
import trelloIcon from './icons/trello.svg' import trelloIcon from './icons/trello.svg?url'
import microsoftTodoIcon from './icons/microsoft-todo.svg' import microsoftTodoIcon from './icons/microsoft-todo.svg?url'
import vikunjaFileIcon from './icons/vikunja-file.png' import vikunjaFileIcon from './icons/vikunja-file.png?url'
export interface Migrator { export interface Migrator {
id: string id: string

View file

@ -38,7 +38,7 @@
</div> </div>
<template v-if="!loading && (!tasks || tasks.length === 0) && showNothingToDo"> <template v-if="!loading && (!tasks || tasks.length === 0) && showNothingToDo">
<h3 class="nothing">{{ $t('task.show.noTasks') }}</h3> <h3 class="nothing">{{ $t('task.show.noTasks') }}</h3>
<img alt="" :src="llamaCoolUrl" /> <LlamaCool class="llama-cool" />
</template> </template>
<div :class="{ 'is-loading': loading}" class="spinner"></div> <div :class="{ 'is-loading': loading}" class="spinner"></div>
@ -64,7 +64,7 @@ import 'flatpickr/dist/flatpickr.css'
import Fancycheckbox from '../../components/input/fancycheckbox' import Fancycheckbox from '../../components/input/fancycheckbox'
import {LOADING, LOADING_MODULE} from '../../store/mutation-types' import {LOADING, LOADING_MODULE} from '../../store/mutation-types'
import llamaCoolUrl from '@/assets/llama-cool.svg' import LlamaCool from '@/assets/llama-cool.svg?component'
export default { export default {
name: 'ShowTasks', name: 'ShowTasks',
@ -72,6 +72,7 @@ export default {
Fancycheckbox, Fancycheckbox,
SingleTaskInList, SingleTaskInList,
flatPickr, flatPickr,
LlamaCool,
}, },
data() { data() {
return { return {
@ -83,7 +84,6 @@ export default {
cEndDate: null, cEndDate: null,
showNothingToDo: false, showNothingToDo: false,
llamaCoolUrl,
} }
}, },
props: { props: {
@ -256,8 +256,7 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.show-tasks { h3 {
h3 {
text-align: left; text-align: left;
&.nothing { &.nothing {
@ -270,14 +269,9 @@ export default {
vertical-align: middle; vertical-align: middle;
margin: .5rem 0; margin: .5rem 0;
} }
} }
img { .llama-cool {
margin-top: 2rem; margin-top: 2rem;
}
.user img {
margin: 0;
}
} }
</style> </style>

View file

@ -4,6 +4,7 @@ import legacyFn from '@vitejs/plugin-legacy'
const {VitePWA} = require('vite-plugin-pwa') const {VitePWA} = require('vite-plugin-pwa')
const path = require('path') const path = require('path')
const {visualizer} = require('rollup-plugin-visualizer') const {visualizer} = require('rollup-plugin-visualizer')
import svgLoader from 'vite-svg-loader'
const pathSrc = path.resolve(__dirname, './src') const pathSrc = path.resolve(__dirname, './src')
@ -42,6 +43,11 @@ export default defineConfig({
}, },
}), }),
legacy, legacy,
svgLoader({
// Since the svgs are already manually optimized via https://jakearchibald.github.io/svgomg/
// we don't need to optimize them again.
svgo: false,
}),
VitePWA({ VitePWA({
srcDir: 'src', srcDir: 'src',
filename: 'sw.js', filename: 'sw.js',

View file

@ -3052,6 +3052,11 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
"@trysound/sax@0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
"@tsconfig/node10@^1.0.7": "@tsconfig/node10@^1.0.7":
version "1.0.8" version "1.0.8"
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
@ -3577,7 +3582,7 @@
"@vue/compiler-core" "3.2.21" "@vue/compiler-core" "3.2.21"
"@vue/shared" "3.2.21" "@vue/shared" "3.2.21"
"@vue/compiler-sfc@3.2.21": "@vue/compiler-sfc@3.2.21", "@vue/compiler-sfc@^3.2.20":
version "3.2.21" version "3.2.21"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.21.tgz#42639ee49e725afb7d8f1d1940e75dc17a56002c" resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.21.tgz#42639ee49e725afb7d8f1d1940e75dc17a56002c"
integrity sha512-+yDlUSebKpz/ovxM2vLRRx7w/gVfY767pOfYTgbIhAs+ogvIV2BsIt4fpxlThnlCNChJ+yE0ERUNoROv2kEGEQ== integrity sha512-+yDlUSebKpz/ovxM2vLRRx7w/gVfY767pOfYTgbIhAs+ogvIV2BsIt4fpxlThnlCNChJ+yE0ERUNoROv2kEGEQ==
@ -4387,6 +4392,11 @@ body-parser@1.19.0:
raw-body "2.4.0" raw-body "2.4.0"
type-is "~1.6.17" type-is "~1.6.17"
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
boxen@^4.2.0: boxen@^4.2.0:
version "4.2.0" version "4.2.0"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64"
@ -5408,6 +5418,37 @@ crypto-random-string@^2.0.0:
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
css-select@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067"
integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==
dependencies:
boolbase "^1.0.0"
css-what "^5.0.0"
domhandler "^4.2.0"
domutils "^2.6.0"
nth-check "^2.0.0"
css-tree@^1.1.2, css-tree@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
dependencies:
mdn-data "2.0.14"
source-map "^0.6.1"
css-what@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe"
integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==
csso@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529"
integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==
dependencies:
css-tree "^1.1.2"
cssom@^0.4.4: cssom@^0.4.4:
version "0.4.4" version "0.4.4"
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
@ -5923,7 +5964,7 @@ dompurify@2.3.3:
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.3.tgz#c1af3eb88be47324432964d8abc75cf4b98d634c" resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.3.tgz#c1af3eb88be47324432964d8abc75cf4b98d634c"
integrity sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg== integrity sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg==
domutils@^2.8.0: domutils@^2.6.0, domutils@^2.8.0:
version "2.8.0" version "2.8.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
@ -9579,6 +9620,11 @@ md5-hex@^3.0.1:
dependencies: dependencies:
blueimp-md5 "^2.10.0" blueimp-md5 "^2.10.0"
mdn-data@2.0.14:
version "2.0.14"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
media-typer@0.3.0: media-typer@0.3.0:
version "0.3.0" version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@ -10296,6 +10342,13 @@ npmlog@^5.0.1:
gauge "^3.0.0" gauge "^3.0.0"
set-blocking "^2.0.0" set-blocking "^2.0.0"
nth-check@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2"
integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==
dependencies:
boolbase "^1.0.0"
number-is-nan@^1.0.0: number-is-nan@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
@ -12132,6 +12185,11 @@ sshpk@^1.7.0:
safer-buffer "^2.0.2" safer-buffer "^2.0.2"
tweetnacl "~0.14.0" tweetnacl "~0.14.0"
stable@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
stack-generator@^2.0.3: stack-generator@^2.0.3:
version "2.0.5" version "2.0.5"
resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36"
@ -12410,6 +12468,19 @@ supports-hyperlinks@^2.0.0, supports-hyperlinks@^2.1.0:
has-flag "^4.0.0" has-flag "^4.0.0"
supports-color "^7.0.0" supports-color "^7.0.0"
svgo@^2.7.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24"
integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==
dependencies:
"@trysound/sax" "0.2.0"
commander "^7.2.0"
css-select "^4.1.3"
css-tree "^1.1.3"
csso "^4.2.0"
picocolors "^1.0.0"
stable "^0.1.8"
symbol-observable@^1.1.0: symbol-observable@^1.1.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
@ -13173,6 +13244,14 @@ vite-plugin-pwa@0.11.3:
workbox-build "^6.3.0" workbox-build "^6.3.0"
workbox-window "^6.3.0" workbox-window "^6.3.0"
vite-svg-loader@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/vite-svg-loader/-/vite-svg-loader-3.1.0.tgz#58d4ed5785583afce10059125467f8bf803e3183"
integrity sha512-dcxLJPQXC3e2/HYrKjOi0fEIzP+Wcny1PhOTsYhnZcqLIhyjAHkMeZwWl9jXC3u+QpUZy4TyLgVnBPuiok3BUA==
dependencies:
"@vue/compiler-sfc" "^3.2.20"
svgo "^2.7.0"
vite@2.6.14: vite@2.6.14:
version "2.6.14" version "2.6.14"
resolved "https://registry.yarnpkg.com/vite/-/vite-2.6.14.tgz#35c09a15e4df823410819a2a239ab11efb186271" resolved "https://registry.yarnpkg.com/vite/-/vite-2.6.14.tgz#35c09a15e4df823410819a2a239ab11efb186271"