minimal working
This commit is contained in:
1 parent
2093433b96
commit
13ea8c80da
11 files changed
+727
-337
No files matched your search
+12
-18
@@ -1,5 +1,7 @@
|
|||||||
import _axios, { AxiosInstance } from 'axios'
|
import _axios, { AxiosInstance } from 'axios'
|
||||||
|
|
||||||
|
const WANIKANI_API_KEY = 'WANIKANI_API_KEY'
|
||||||
|
|
||||||
export type ITypeLevel = 'character' | 'vocabulary'
|
export type ITypeLevel = 'character' | 'vocabulary'
|
||||||
export type IType = ITypeLevel | 'sentence'
|
export type IType = ITypeLevel | 'sentence'
|
||||||
|
|
||||||
@@ -93,35 +95,27 @@ class Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async setWanikaniApiKey(apiKey?: string) {
|
async setWanikaniApiKey(apiKey?: string) {
|
||||||
|
apiKey = apiKey || localStorage.getItem(WANIKANI_API_KEY) || ''
|
||||||
|
console.log(apiKey)
|
||||||
|
|
||||||
const setApiKey = () => {
|
const setApiKey = () => {
|
||||||
if (apiKey) {
|
if (apiKey) {
|
||||||
this.axios.defaults.headers.common['Authorization'] = `Bearer ${apiKey}`
|
this.axios.defaults.headers.common['Authorization'] = `Bearer ${apiKey}`
|
||||||
|
localStorage.setItem(WANIKANI_API_KEY, apiKey)
|
||||||
} else {
|
} else {
|
||||||
delete this.axios.defaults.headers.common['Authorization']
|
delete this.axios.defaults.headers.common['Authorization']
|
||||||
|
localStorage.removeItem(WANIKANI_API_KEY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setApiKey()
|
setApiKey()
|
||||||
|
const r = await window.$nuxt.$accessor.updateSettings()
|
||||||
|
|
||||||
return await this.isAuthorized().then((r) => {
|
if (!r) {
|
||||||
if (!r) {
|
apiKey = ''
|
||||||
apiKey = ''
|
setApiKey()
|
||||||
setApiKey()
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async isAuthorized(): Promise<boolean> {
|
|
||||||
if (this._isAuthorized && !this._user) {
|
|
||||||
const r = await this.user_getSettings({ select: ['identifier'] })
|
|
||||||
if (r) {
|
|
||||||
this._user = r.identifier
|
|
||||||
this._isAuthorized = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return r
|
||||||
return this._isAuthorized
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async user_getSettings(params: { select: (keyof IUserSettings)[] }) {
|
async user_getSettings(params: { select: (keyof IUserSettings)[] }) {
|
||||||
|
|||||||
+100
-177
@@ -30,12 +30,10 @@
|
|||||||
<div class="column is-6 entry-display">
|
<div class="column is-6 entry-display">
|
||||||
<div
|
<div
|
||||||
class="character-display clickable font-han"
|
class="character-display clickable font-han"
|
||||||
@click="(evt) => openContext(evt, current, 'character')"
|
@click="(evt) => openContext(evt, entry)"
|
||||||
@contextmenu.prevent="
|
@contextmenu.prevent="(evt) => openContext(evt, entry)"
|
||||||
(evt) => openContext(evt, current, 'character')
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{{ current }}
|
{{ entry.entry }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="buttons has-addons">
|
<div class="buttons has-addons">
|
||||||
@@ -57,7 +55,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="tag.length" class="mb-4">
|
<div v-if="entry.tag.length" class="mb-4">
|
||||||
Tags:
|
Tags:
|
||||||
<b-taglist style="display: inline-flex">
|
<b-taglist style="display: inline-flex">
|
||||||
<b-tag v-for="t in tag.slice(0, 5)" :key="t" type="is-info">
|
<b-tag v-for="t in tag.slice(0, 5)" :key="t" type="is-info">
|
||||||
@@ -66,11 +64,11 @@
|
|||||||
</b-taglist>
|
</b-taglist>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="level && level <= 60" class="mb-4">
|
<div v-if="entry.level <= 60" class="mb-4">
|
||||||
<b-taglist attached>
|
<b-taglist attached>
|
||||||
<b-tag type="is-dark">Level</b-tag>
|
<b-tag type="is-dark">Level</b-tag>
|
||||||
<b-tag type="is-primary">
|
<b-tag type="is-primary">
|
||||||
{{ level }}
|
{{ entry.level }}
|
||||||
</b-tag>
|
</b-tag>
|
||||||
</b-taglist>
|
</b-taglist>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,14 +89,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
{{ reading.join(' / ') }}
|
{{ entry.reading.join(' / ') }}
|
||||||
</div>
|
</div>
|
||||||
</b-collapse>
|
</b-collapse>
|
||||||
|
|
||||||
<b-collapse
|
<b-collapse
|
||||||
class="card"
|
class="card"
|
||||||
animation="slide"
|
animation="slide"
|
||||||
:open="!!translation.length"
|
:open="!!entry.translation.length"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
@@ -113,11 +111,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
{{ translation.join(' / ') }}
|
{{ entry.translation.join(' / ') }}
|
||||||
</div>
|
</div>
|
||||||
</b-collapse>
|
</b-collapse>
|
||||||
|
|
||||||
<b-collapse class="card" animation="slide" :open="!!sub.length">
|
<b-collapse class="card" animation="slide" :open="!!entry.sub.length">
|
||||||
<div
|
<div
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
slot-scope="props"
|
slot-scope="props"
|
||||||
@@ -132,18 +130,22 @@
|
|||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<span
|
<span
|
||||||
v-for="h in sub"
|
v-for="h in entry.sub"
|
||||||
:key="h"
|
:key="h"
|
||||||
class="font-han clickable"
|
class="font-han clickable"
|
||||||
@click="(evt) => openContext(evt, h, 'character')"
|
@click="
|
||||||
@contextmenu.prevent="(evt) => openContext(evt, h, 'character')"
|
(evt) => openContext(evt, { entry: h, type: 'character' })
|
||||||
|
"
|
||||||
|
@contextmenu.prevent="
|
||||||
|
(evt) => openContext(evt, { entry: h, type: 'character' })
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ h }}
|
{{ h }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</b-collapse>
|
</b-collapse>
|
||||||
|
|
||||||
<b-collapse class="card" animation="slide" :open="!!sup.length">
|
<b-collapse class="card" animation="slide" :open="!!entry.sup.length">
|
||||||
<div
|
<div
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
slot-scope="props"
|
slot-scope="props"
|
||||||
@@ -158,18 +160,26 @@
|
|||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<span
|
<span
|
||||||
v-for="h in sup"
|
v-for="h in entry.sup"
|
||||||
:key="h"
|
:key="h"
|
||||||
class="font-han clickable"
|
class="font-han clickable"
|
||||||
@click="(evt) => openContext(evt, h, 'character')"
|
@click="
|
||||||
@contextmenu.prevent="(evt) => openContext(evt, h, 'character')"
|
(evt) => openContext(evt, { entry: h, type: 'character' })
|
||||||
|
"
|
||||||
|
@contextmenu.prevent="
|
||||||
|
(evt) => openContext(evt, { entry: h, type: 'character' })
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ h }}
|
{{ h }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</b-collapse>
|
</b-collapse>
|
||||||
|
|
||||||
<b-collapse class="card" animation="slide" :open="!!variants.length">
|
<b-collapse
|
||||||
|
class="card"
|
||||||
|
animation="slide"
|
||||||
|
:open="!!entry.variant.length"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
slot-scope="props"
|
slot-scope="props"
|
||||||
@@ -184,82 +194,20 @@
|
|||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<span
|
<span
|
||||||
v-for="h in variants"
|
v-for="h in entry.variant"
|
||||||
:key="h"
|
:key="h"
|
||||||
class="font-han clickable"
|
class="font-han clickable"
|
||||||
@click="(evt) => openContext(evt, h, 'character')"
|
@click="
|
||||||
@contextmenu.prevent="(evt) => openContext(evt, h, 'character')"
|
(evt) => openContext(evt, { entry: h, type: 'character' })
|
||||||
|
"
|
||||||
|
@contextmenu.prevent="
|
||||||
|
(evt) => openContext(evt, { entry: h, type: 'character' })
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ h }}
|
{{ h }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</b-collapse>
|
</b-collapse>
|
||||||
|
|
||||||
<b-collapse class="card" animation="slide" :open="!!vocabs.length">
|
|
||||||
<div
|
|
||||||
slot="trigger"
|
|
||||||
slot-scope="props"
|
|
||||||
class="card-header"
|
|
||||||
role="button"
|
|
||||||
>
|
|
||||||
<h2 class="card-header-title">Vocabularies</h2>
|
|
||||||
<a role="button" class="card-header-icon">
|
|
||||||
<fontawesome :icon="props.open ? 'caret-down' : 'caret-up'" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-content">
|
|
||||||
<div v-for="(v, i) in vocabs" :key="i" class="long-item">
|
|
||||||
<span
|
|
||||||
class="clickable"
|
|
||||||
@click="(evt) => openContext(evt, v.entry, 'vocabulary')"
|
|
||||||
@contextmenu.prevent="
|
|
||||||
(evt) => openContext(evt, v.entry, 'vocabulary')
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ v.entry }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-if="v.alt" class="clickable">
|
|
||||||
{{ v.alt.join(' ') }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="pinyin">[{{ v.reading.join(' / ') }}]</span>
|
|
||||||
|
|
||||||
<span>{{ v.translation.join(' / ') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</b-collapse>
|
|
||||||
|
|
||||||
<b-collapse class="card" animation="slide" :open="!!sentences.length">
|
|
||||||
<div
|
|
||||||
slot="trigger"
|
|
||||||
slot-scope="props"
|
|
||||||
class="card-header"
|
|
||||||
role="button"
|
|
||||||
>
|
|
||||||
<h2 class="card-header-title">Sentences</h2>
|
|
||||||
<a role="button" class="card-header-icon">
|
|
||||||
<fontawesome :icon="props.open ? 'caret-down' : 'caret-up'" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-content">
|
|
||||||
<div v-for="(s, i) in sentences" :key="i" class="long-item">
|
|
||||||
<span
|
|
||||||
class="clickable"
|
|
||||||
@click="(evt) => openContext(evt, s.entry[0], 'sentence')"
|
|
||||||
@contextmenu.prevent="
|
|
||||||
(evt) => openContext(evt, s.entry[0], 'sentence')
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ s.entry[0] }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span>{{ s.translation[0] }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</b-collapse>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -278,10 +226,31 @@
|
|||||||
import { Component, Prop, Ref, Vue, Watch } from 'nuxt-property-decorator'
|
import { Component, Prop, Ref, Vue, Watch } from 'nuxt-property-decorator'
|
||||||
import ContextMenu from '@/components/ContextMenu.vue'
|
import ContextMenu from '@/components/ContextMenu.vue'
|
||||||
import { api, IDictionaryLookup, IEntryLookup, IType } from '~/assets/api'
|
import { api, IDictionaryLookup, IEntryLookup, IType } from '~/assets/api'
|
||||||
import { capitalize } from '~/assets/util'
|
|
||||||
|
|
||||||
type ILookupEntry = Omit<IDictionaryLookup, 'id'> & IEntryLookup
|
type ILookupEntry = Omit<IDictionaryLookup, 'id'> & IEntryLookup
|
||||||
|
|
||||||
|
const makeLookupEntry = (
|
||||||
|
entry = '',
|
||||||
|
type: IType = 'vocabulary'
|
||||||
|
): ILookupEntry => {
|
||||||
|
return {
|
||||||
|
entry,
|
||||||
|
list: [],
|
||||||
|
type,
|
||||||
|
reading: [],
|
||||||
|
translation: [],
|
||||||
|
audio: [],
|
||||||
|
description: '',
|
||||||
|
tag: [],
|
||||||
|
sub: [],
|
||||||
|
sup: [],
|
||||||
|
variant: [],
|
||||||
|
visual: [],
|
||||||
|
amalgamation: [],
|
||||||
|
component: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Component<LookupTab>({
|
@Component<LookupTab>({
|
||||||
components: {
|
components: {
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
@@ -300,13 +269,12 @@ export default class LookupTab extends Vue {
|
|||||||
@Prop({ default: () => ({}) }) query!: {
|
@Prop({ default: () => ({}) }) query!: {
|
||||||
q?: string
|
q?: string
|
||||||
entry?: string
|
entry?: string
|
||||||
|
type?: 'character' | 'vocabulary'
|
||||||
}
|
}
|
||||||
|
|
||||||
@Prop() type!: 'character' | 'vocabulary'
|
|
||||||
|
|
||||||
@Ref() context!: ContextMenu
|
@Ref() context!: ContextMenu
|
||||||
|
|
||||||
title = this.type === 'character' ? 'Kanji' : capitalize(this.type)
|
title = 'Lookup'
|
||||||
|
|
||||||
entries: ILookupEntry[] = []
|
entries: ILookupEntry[] = []
|
||||||
i = 0
|
i = 0
|
||||||
@@ -320,6 +288,7 @@ export default class LookupTab extends Vue {
|
|||||||
selected: {
|
selected: {
|
||||||
entry: string
|
entry: string
|
||||||
type: string
|
type: string
|
||||||
|
audio?: ILookupEntry['audio']
|
||||||
} = {
|
} = {
|
||||||
entry: '',
|
entry: '',
|
||||||
type: '',
|
type: '',
|
||||||
@@ -328,8 +297,8 @@ export default class LookupTab extends Vue {
|
|||||||
q = ''
|
q = ''
|
||||||
q0 = ''
|
q0 = ''
|
||||||
|
|
||||||
get current() {
|
get entry() {
|
||||||
return this.entries[this.i]?.entry || ''
|
return this.entries[this.i] || makeLookupEntry()
|
||||||
}
|
}
|
||||||
|
|
||||||
get additionalContext() {
|
get additionalContext() {
|
||||||
@@ -338,7 +307,7 @@ export default class LookupTab extends Vue {
|
|||||||
{
|
{
|
||||||
name: 'Reload',
|
name: 'Reload',
|
||||||
handler: async () => {
|
handler: async () => {
|
||||||
const { result } = await api.all_getRandom({ type: this.type })
|
const { result } = await api.all_getRandom({ type: 'vocabulary' })
|
||||||
this.q0 = result
|
this.q0 = result
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -348,12 +317,8 @@ export default class LookupTab extends Vue {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
openContext(
|
openContext(evt: MouseEvent, entry = this.selected) {
|
||||||
evt: MouseEvent,
|
this.selected = entry
|
||||||
entry = this.selected.entry,
|
|
||||||
type = this.selected.type
|
|
||||||
) {
|
|
||||||
this.selected = { entry, type }
|
|
||||||
this.context.open(evt)
|
this.context.open(evt)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,72 +327,23 @@ export default class LookupTab extends Vue {
|
|||||||
this.$emit('title', (q ? q + ' - ' : '') + this.title)
|
this.$emit('title', (q ? q + ' - ' : '') + this.title)
|
||||||
this.entries = []
|
this.entries = []
|
||||||
|
|
||||||
if (this.type === 'character') {
|
if (q.trim()) {
|
||||||
if (/\p{sc=Han}/u.test(q)) {
|
const r = await api.all_getQuery({
|
||||||
let qs = q.split('').filter((h) => /\p{sc=Han}/u.test(h))
|
q,
|
||||||
qs = qs.filter((h, i) => qs.indexOf(h) === i)
|
type: this.query.type,
|
||||||
|
distinct: 'id',
|
||||||
this.entries = qs.map(
|
})
|
||||||
(entry) =>
|
this.entries = r.result.map(({ entry, type }) =>
|
||||||
({
|
makeLookupEntry(entry, type)
|
||||||
entry,
|
)
|
||||||
list: [],
|
|
||||||
type: this.type,
|
|
||||||
reading: [],
|
|
||||||
translation: [],
|
|
||||||
audio: [],
|
|
||||||
description: '',
|
|
||||||
tag: [],
|
|
||||||
sub: [],
|
|
||||||
sup: [],
|
|
||||||
variant: [],
|
|
||||||
visual: [],
|
|
||||||
amalgamation: [],
|
|
||||||
component: [],
|
|
||||||
} as ILookupEntry)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
if (!q.trim()) {
|
|
||||||
const { result } = await api.all_getRandom({ type: this.type })
|
|
||||||
|
|
||||||
this.q0 = result
|
|
||||||
this.q = result
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
const r = await api.all_getQuery({
|
|
||||||
q,
|
|
||||||
type: this.type,
|
|
||||||
distinct: 'id',
|
|
||||||
})
|
|
||||||
this.entries = r.result.map(
|
|
||||||
({ entry }) =>
|
|
||||||
({
|
|
||||||
entry,
|
|
||||||
list: [],
|
|
||||||
type: this.type,
|
|
||||||
reading: [],
|
|
||||||
translation: [],
|
|
||||||
audio: [],
|
|
||||||
description: '',
|
|
||||||
tag: [],
|
|
||||||
sub: [],
|
|
||||||
sup: [],
|
|
||||||
variant: [],
|
|
||||||
visual: [],
|
|
||||||
amalgamation: [],
|
|
||||||
component: [],
|
|
||||||
} as ILookupEntry)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.i = 0
|
this.i = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@Watch('current')
|
@Watch('entry.entry')
|
||||||
load() {
|
load() {
|
||||||
if (this.current) {
|
if (this.entry.entry) {
|
||||||
this.loadComponents()
|
this.loadComponents()
|
||||||
this.loadVocabularies()
|
this.loadVocabularies()
|
||||||
this.loadSentences()
|
this.loadSentences()
|
||||||
@@ -441,17 +357,18 @@ export default class LookupTab extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadComponents() {
|
async loadComponents() {
|
||||||
if (!this.current.trim()) return
|
const entry = this.entries[this.i]
|
||||||
|
if (!entry) return
|
||||||
|
|
||||||
const [comp, dict] = await Promise.all([
|
const [comp, dict] = await Promise.all([
|
||||||
api.all_getComponent({
|
api.all_getComponent({
|
||||||
entry: this.current,
|
entry: entry.entry,
|
||||||
type: this.type,
|
type: entry.type,
|
||||||
}),
|
}),
|
||||||
api
|
api
|
||||||
.all_getLookup({
|
.all_getLookup({
|
||||||
entry: this.current,
|
entry: entry.entry,
|
||||||
type: this.type,
|
type: entry.type,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
})
|
})
|
||||||
.then(({ result: [r] }) => r),
|
.then(({ result: [r] }) => r),
|
||||||
@@ -459,9 +376,9 @@ export default class LookupTab extends Vue {
|
|||||||
|
|
||||||
this.$set(this.entries, this.i, {
|
this.$set(this.entries, this.i, {
|
||||||
...(dict || {
|
...(dict || {
|
||||||
entry: this.current,
|
entry: entry.entry,
|
||||||
list: [],
|
list: [],
|
||||||
type: this.type,
|
type: entry.type,
|
||||||
reading: [],
|
reading: [],
|
||||||
translation: [],
|
translation: [],
|
||||||
audio: [],
|
audio: [],
|
||||||
@@ -480,22 +397,25 @@ export default class LookupTab extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadVocabularies() {
|
async loadVocabularies() {
|
||||||
if (this.type === 'character') {
|
const entry = this.entries[this.i]
|
||||||
if (!/^\p{sc=Han}$/u.test(this.current)) {
|
if (!entry) return
|
||||||
|
|
||||||
|
if (entry.type === 'character') {
|
||||||
|
if (!/^\p{sc=Han}$/u.test(entry.entry)) {
|
||||||
this.lookup.vocabulary = []
|
this.lookup.vocabulary = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lookup.vocabulary = await api
|
this.lookup.vocabulary = await api
|
||||||
.character_getVocabulary({
|
.character_getVocabulary({
|
||||||
entry: this.current,
|
entry: entry.entry,
|
||||||
distinct: 'id',
|
distinct: 'id',
|
||||||
})
|
})
|
||||||
.then((r) => r.result)
|
.then((r) => r.result)
|
||||||
} else {
|
} else {
|
||||||
this.lookup.vocabulary = await api
|
this.lookup.vocabulary = await api
|
||||||
.vocabulary_getVocabulary({
|
.vocabulary_getVocabulary({
|
||||||
entry: this.current,
|
entry: entry.entry,
|
||||||
distinct: 'id',
|
distinct: 'id',
|
||||||
})
|
})
|
||||||
.then((r) => r.result)
|
.then((r) => r.result)
|
||||||
@@ -503,22 +423,25 @@ export default class LookupTab extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadSentences() {
|
async loadSentences() {
|
||||||
if (this.type === 'character') {
|
const entry = this.entries[this.i]
|
||||||
if (!/^\p{sc=Han}$/u.test(this.current)) {
|
if (!entry) return
|
||||||
|
|
||||||
|
if (entry.type === 'character') {
|
||||||
|
if (!/^\p{sc=Han}$/u.test(entry.entry)) {
|
||||||
this.lookup.sentence = []
|
this.lookup.sentence = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lookup.sentence = await api
|
this.lookup.sentence = await api
|
||||||
.character_getSentence({
|
.character_getSentence({
|
||||||
entry: this.current,
|
entry: entry.entry,
|
||||||
distinct: 'id',
|
distinct: 'id',
|
||||||
})
|
})
|
||||||
.then((r) => r.result)
|
.then((r) => r.result)
|
||||||
} else {
|
} else {
|
||||||
this.lookup.sentence = await api
|
this.lookup.sentence = await api
|
||||||
.vocabulary_getSentence({
|
.vocabulary_getSentence({
|
||||||
entry: this.current,
|
entry: entry.entry,
|
||||||
distinct: 'id',
|
distinct: 'id',
|
||||||
})
|
})
|
||||||
.then((r) => r.result)
|
.then((r) => r.result)
|
||||||
|
|||||||
+31
-68
@@ -1,74 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="DefaultLayout">
|
||||||
<nav
|
<nuxt />
|
||||||
class="navbar header has-shadow is-primary"
|
|
||||||
role="navigation"
|
|
||||||
aria-label="main navigation"
|
|
||||||
>
|
|
||||||
<div class="navbar-brand">
|
|
||||||
<a
|
|
||||||
class="navbar-item"
|
|
||||||
href="/"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="~assets/buefy.png"
|
|
||||||
alt="Buefy"
|
|
||||||
height="28"
|
|
||||||
>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="navbar-burger">
|
|
||||||
<span />
|
|
||||||
<span />
|
|
||||||
<span />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<section class="main-content columns">
|
|
||||||
<aside class="column is-2 section">
|
|
||||||
<p class="menu-label is-hidden-touch">
|
|
||||||
General
|
|
||||||
</p>
|
|
||||||
<ul class="menu-list">
|
|
||||||
<li
|
|
||||||
v-for="(item, key) of items"
|
|
||||||
:key="key"
|
|
||||||
>
|
|
||||||
<NuxtLink
|
|
||||||
:to="item.to"
|
|
||||||
exact-active-class="is-active"
|
|
||||||
>
|
|
||||||
<b-icon :icon="item.icon" /> {{ item.title }}
|
|
||||||
</NuxtLink>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<div class="container column is-10">
|
|
||||||
<Nuxt />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
export default {
|
import { Vue, Component } from 'nuxt-property-decorator'
|
||||||
data () {
|
import '~/assets/speak'
|
||||||
return {
|
|
||||||
items: [
|
@Component<DefaultLayout>({
|
||||||
{
|
mounted() {
|
||||||
title: 'Home',
|
if (process.env['NODE_ENV'] !== 'development') {
|
||||||
icon: 'home',
|
window.onbeforeunload = function (e: any) {
|
||||||
to: { name: 'index' }
|
e.preventDefault()
|
||||||
},
|
e.returnValue = 'not returned'
|
||||||
{
|
}
|
||||||
title: 'Inspire',
|
|
||||||
icon: 'lightbulb',
|
|
||||||
to: { name: 'inspire' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
})
|
||||||
|
export default class DefaultLayout extends Vue {}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#__nuxt,
|
||||||
|
#__layout,
|
||||||
|
.DefaultLayout {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
overscroll-behavior-y: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+55
-3
@@ -1,6 +1,8 @@
|
|||||||
import { NuxtConfig } from '@nuxt/types'
|
import { NuxtConfig } from '@nuxt/types'
|
||||||
|
|
||||||
export default async (): Promise<NuxtConfig> => {
|
export default async (): Promise<NuxtConfig> => {
|
||||||
|
const NODE_ENV = process.env['NODE_ENV'] || ''
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
|
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
|
||||||
ssr: false,
|
ssr: false,
|
||||||
@@ -10,11 +12,15 @@ export default async (): Promise<NuxtConfig> => {
|
|||||||
|
|
||||||
// Global page headers: https://go.nuxtjs.dev/config-head
|
// Global page headers: https://go.nuxtjs.dev/config-head
|
||||||
head: {
|
head: {
|
||||||
title: 'jaquiz',
|
title: 'WaniKani-based jaquiz',
|
||||||
meta: [
|
meta: [
|
||||||
{ charset: 'utf-8' },
|
{ charset: 'utf-8' },
|
||||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||||
{ hid: 'description', name: 'description', content: '' },
|
{
|
||||||
|
hid: 'description',
|
||||||
|
name: 'description',
|
||||||
|
content: 'WaniKani-based jaquiz',
|
||||||
|
},
|
||||||
{ name: 'format-detection', content: 'telephone=no' },
|
{ name: 'format-detection', content: 'telephone=no' },
|
||||||
],
|
],
|
||||||
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
|
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
|
||||||
@@ -24,7 +30,7 @@ export default async (): Promise<NuxtConfig> => {
|
|||||||
css: [],
|
css: [],
|
||||||
|
|
||||||
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
||||||
plugins: [],
|
plugins: ['~/plugins/filter.ts', '~/plugins/vue-context.client.js'],
|
||||||
|
|
||||||
// Auto import components: https://go.nuxtjs.dev/config-components
|
// Auto import components: https://go.nuxtjs.dev/config-components
|
||||||
components: true,
|
components: true,
|
||||||
@@ -33,6 +39,7 @@ export default async (): Promise<NuxtConfig> => {
|
|||||||
buildModules: [
|
buildModules: [
|
||||||
// https://go.nuxtjs.dev/typescript
|
// https://go.nuxtjs.dev/typescript
|
||||||
'@nuxt/typescript-build',
|
'@nuxt/typescript-build',
|
||||||
|
'nuxt-typed-vuex',
|
||||||
],
|
],
|
||||||
|
|
||||||
// Modules: https://go.nuxtjs.dev/config-modules
|
// Modules: https://go.nuxtjs.dev/config-modules
|
||||||
@@ -41,6 +48,43 @@ export default async (): Promise<NuxtConfig> => {
|
|||||||
'nuxt-buefy',
|
'nuxt-buefy',
|
||||||
// https://go.nuxtjs.dev/pwa
|
// https://go.nuxtjs.dev/pwa
|
||||||
'@nuxtjs/pwa',
|
'@nuxtjs/pwa',
|
||||||
|
'@nuxtjs/proxy',
|
||||||
|
[
|
||||||
|
'@nuxtjs/fontawesome',
|
||||||
|
{
|
||||||
|
component: 'fontawesome',
|
||||||
|
icons: {
|
||||||
|
brands: ['faGithub'],
|
||||||
|
solid: [
|
||||||
|
'faAngleLeft',
|
||||||
|
'faAngleRight',
|
||||||
|
'faAngleUp',
|
||||||
|
'faArrowUp',
|
||||||
|
'faBookReader',
|
||||||
|
'faCaretDown',
|
||||||
|
'faCaretUp',
|
||||||
|
'faChalkboardTeacher',
|
||||||
|
'faCog',
|
||||||
|
'faExclamationCircle',
|
||||||
|
'faExclamationTriangle',
|
||||||
|
'faEye',
|
||||||
|
'faEyeSlash',
|
||||||
|
'faInfoCircle',
|
||||||
|
'faRandom',
|
||||||
|
'faSearch',
|
||||||
|
'faTag',
|
||||||
|
'faListUl',
|
||||||
|
'faListOl',
|
||||||
|
'faBars',
|
||||||
|
'faSave',
|
||||||
|
'faTrash',
|
||||||
|
'faTools',
|
||||||
|
'faTh',
|
||||||
|
'faRedoAlt',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
// PWA module configuration: https://go.nuxtjs.dev/pwa
|
// PWA module configuration: https://go.nuxtjs.dev/pwa
|
||||||
@@ -50,6 +94,14 @@ export default async (): Promise<NuxtConfig> => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
proxy: {
|
||||||
|
'/api': 'http://localhost:35594',
|
||||||
|
},
|
||||||
|
|
||||||
|
env: {
|
||||||
|
NODE_ENV,
|
||||||
|
},
|
||||||
|
|
||||||
// Build Configuration: https://go.nuxtjs.dev/config-build
|
// Build Configuration: https://go.nuxtjs.dev/config-build
|
||||||
build: {},
|
build: {},
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-8
@@ -9,22 +9,28 @@
|
|||||||
"generate": "nuxt generate"
|
"generate": "nuxt generate"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||||
|
"@fortawesome/free-brands-svg-icons": "^5.15.4",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||||
|
"@fortawesome/vue-fontawesome": "^2.0.6",
|
||||||
|
"@nuxtjs/fontawesome": "^1.1.2",
|
||||||
|
"@nuxtjs/proxy": "^2.1.0",
|
||||||
"@nuxtjs/pwa": "^3.3.5",
|
"@nuxtjs/pwa": "^3.3.5",
|
||||||
"axios": "^0.23.0",
|
"axios": "^0.24.0",
|
||||||
"core-js": "^3.15.1",
|
"core-js": "^3.19.0",
|
||||||
"jsonschema-definer": "^1.3.2",
|
"jsonschema-definer": "^1.3.2",
|
||||||
"nuxt": "^2.15.7",
|
"nuxt": "^2.15.8",
|
||||||
"nuxt-buefy": "^0.4.8",
|
"nuxt-buefy": "^0.4.11",
|
||||||
"nuxt-property-decorator": "^2.9.1",
|
"nuxt-property-decorator": "^2.9.1",
|
||||||
"nuxt-typed-vuex": "^0.2.0",
|
"nuxt-typed-vuex": "^0.2.0",
|
||||||
"vue-context": "^6.0.0"
|
"vue-context": "^6.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/types": "^2.15.7",
|
"@nuxt/types": "^2.15.8",
|
||||||
"@nuxt/typescript-build": "^2.1.0",
|
"@nuxt/typescript-build": "^2.1.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.4.1",
|
||||||
"sass": "^1.43.3",
|
"sass": "^1.43.4",
|
||||||
"sass-loader": "~10.1.1"
|
"sass-loader": "~10.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-5
@@ -129,16 +129,14 @@ import { api } from '~/assets/api'
|
|||||||
LibraryTab,
|
LibraryTab,
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
await this.$accessor.updateSettings()
|
if (await api.setWanikaniApiKey()) {
|
||||||
|
|
||||||
if (!this.$accessor.isApp) {
|
|
||||||
this.$router.replace('/')
|
|
||||||
} else {
|
|
||||||
this.$accessor.ADD_TAB({
|
this.$accessor.ADD_TAB({
|
||||||
component: 'Lookup',
|
component: 'Lookup',
|
||||||
first: true,
|
first: true,
|
||||||
})
|
})
|
||||||
this.isReady = true
|
this.isReady = true
|
||||||
|
} else {
|
||||||
|
this.$router.replace('/')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ import { api } from '~/assets/api'
|
|||||||
|
|
||||||
@Component<HomePage>({
|
@Component<HomePage>({
|
||||||
async mounted() {
|
async mounted() {
|
||||||
if (await api.isAuthorized()) {
|
if (await api.setWanikaniApiKey()) {
|
||||||
this.$router.replace('/app')
|
this.$router.replace('/app')
|
||||||
} else {
|
} else {
|
||||||
this.isReady = true
|
this.isReady = true
|
||||||
|
|||||||
@@ -0,0 +1,337 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
Vue.filter('format', (v: any) => {
|
||||||
|
if (typeof v === 'number') {
|
||||||
|
return v || v === 0 ? v.toLocaleString() : ''
|
||||||
|
} else if (v instanceof Date) {
|
||||||
|
return v.toLocaleDateString([], {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
weekday: 'short',
|
||||||
|
})
|
||||||
|
} else if (v && typeof v === 'object') {
|
||||||
|
return JSON.stringify(v)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
})
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
Vue.filter('formatDate', (v: any) => {
|
||||||
|
return v
|
||||||
|
? new Date(v).toLocaleDateString([], {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
weekday: 'short',
|
||||||
|
})
|
||||||
|
: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
Vue.filter('duration', (v: any) => {
|
||||||
|
return v
|
||||||
|
? new Duration(new Date(v), new Date()).toString({
|
||||||
|
sign: false,
|
||||||
|
granularity: 2,
|
||||||
|
})
|
||||||
|
: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible duration units in this parser
|
||||||
|
*/
|
||||||
|
export type DurationUnit = 'ms' | 's' | 'min' | 'h' | 'd' | 'w' | 'mo' | 'y'
|
||||||
|
|
||||||
|
export interface IDurationOptions {
|
||||||
|
/**
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
sign?: boolean
|
||||||
|
/**
|
||||||
|
* Number of units plus subunits
|
||||||
|
*/
|
||||||
|
granularity?: number
|
||||||
|
/**
|
||||||
|
* Number of max units shown
|
||||||
|
*/
|
||||||
|
maxUnit?: number
|
||||||
|
/**
|
||||||
|
* Smallest unit shown
|
||||||
|
*
|
||||||
|
* @default 's'
|
||||||
|
*/
|
||||||
|
smallest?: DurationUnit
|
||||||
|
/**
|
||||||
|
* Custom naming for units
|
||||||
|
*/
|
||||||
|
unit?: Partial<Record<DurationUnit, string>>
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Duration {
|
||||||
|
/**
|
||||||
|
* Sign in front of the output toString()
|
||||||
|
*/
|
||||||
|
sign: '+' | '-' | '' = '+'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Milliseconds
|
||||||
|
*/
|
||||||
|
ms: number
|
||||||
|
/**
|
||||||
|
* Seconds
|
||||||
|
*/
|
||||||
|
s: number
|
||||||
|
/**
|
||||||
|
* Minutes
|
||||||
|
*/
|
||||||
|
min: number
|
||||||
|
/**
|
||||||
|
* Hours
|
||||||
|
*/
|
||||||
|
h: number
|
||||||
|
/**
|
||||||
|
* Days
|
||||||
|
*/
|
||||||
|
d: number
|
||||||
|
/**
|
||||||
|
* Weeks
|
||||||
|
*/
|
||||||
|
w: number
|
||||||
|
/**
|
||||||
|
* Months
|
||||||
|
*/
|
||||||
|
mo: number
|
||||||
|
/**
|
||||||
|
* Years
|
||||||
|
*/
|
||||||
|
y: number
|
||||||
|
|
||||||
|
private _dates: [Date, Date] = [new Date(this.from), new Date(this.to)]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse milliseconds (i.e. epoch) to Duration, based on before present time
|
||||||
|
*/
|
||||||
|
static of(msec: number) {
|
||||||
|
const to = new Date()
|
||||||
|
const output = new this(new Date(+to - msec), to)
|
||||||
|
output.sign = ''
|
||||||
|
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
/**
|
||||||
|
* Starting Date
|
||||||
|
*/
|
||||||
|
public from: Date,
|
||||||
|
/**
|
||||||
|
* Ending date
|
||||||
|
*/
|
||||||
|
public to: Date
|
||||||
|
) {
|
||||||
|
if (from > to) {
|
||||||
|
this.sign = '-'
|
||||||
|
this._dates = this._dates.reverse() as [Date, Date]
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ms = this._parse((d) => d.getMilliseconds(), {
|
||||||
|
get: (d) => d.getSeconds(),
|
||||||
|
set: (d, v) => d.setSeconds(v),
|
||||||
|
inc: () => 1000,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.s = this._parse((d) => d.getSeconds(), {
|
||||||
|
get: (d) => d.getMinutes(),
|
||||||
|
set: (d, v) => d.setMinutes(v),
|
||||||
|
inc: () => 60,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.min = this._parse((d) => d.getMinutes(), {
|
||||||
|
get: (d) => d.getHours(),
|
||||||
|
set: (d, v) => d.setHours(v),
|
||||||
|
inc: () => 60,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.h = this._parse((d) => d.getHours(), {
|
||||||
|
get: (d) => d.getDate(),
|
||||||
|
set: (d, v) => d.setDate(v),
|
||||||
|
inc: () => 24,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.d = this._parse((d) => d.getDate(), {
|
||||||
|
get: (d) => d.getMonth(),
|
||||||
|
set: (d, v) => d.setMonth(v),
|
||||||
|
inc: (d) => {
|
||||||
|
const y = d.getFullYear()
|
||||||
|
let isLeapYear = true
|
||||||
|
if (y % 4) {
|
||||||
|
isLeapYear = false
|
||||||
|
} else if (y % 100) {
|
||||||
|
isLeapYear = true
|
||||||
|
} else if (y % 400) {
|
||||||
|
isLeapYear = false
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
31, // Jan
|
||||||
|
isLeapYear ? 29 : 28, // Feb
|
||||||
|
31, // Mar
|
||||||
|
30, // Apr
|
||||||
|
31, // May
|
||||||
|
30, // Jun
|
||||||
|
31, // Jul
|
||||||
|
31, // Aug
|
||||||
|
30, // Sep
|
||||||
|
31, // Oct
|
||||||
|
30, // Nov
|
||||||
|
31, // Dec
|
||||||
|
][d.getMonth()]!
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
this.w = Math.floor(this.d / 7)
|
||||||
|
this.d = this.d % 7
|
||||||
|
|
||||||
|
this.mo = this._parse((d) => d.getMonth(), {
|
||||||
|
get: (d) => d.getFullYear(),
|
||||||
|
set: (d, v) => d.setFullYear(v),
|
||||||
|
inc: () => 12,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.y = this._parse((d) => d.getFullYear())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To JSON-serializable OrderedDict
|
||||||
|
*/
|
||||||
|
toOrderedDict(): [DurationUnit, number][] {
|
||||||
|
return [
|
||||||
|
['ms', this.ms],
|
||||||
|
['s', this.s],
|
||||||
|
['min', this.min],
|
||||||
|
['h', this.h],
|
||||||
|
['d', this.d],
|
||||||
|
['w', this.w],
|
||||||
|
['mo', this.mo],
|
||||||
|
['y', this.y],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To String
|
||||||
|
*
|
||||||
|
* Works with `${duration}` also
|
||||||
|
*/
|
||||||
|
toString({
|
||||||
|
sign = true,
|
||||||
|
granularity,
|
||||||
|
maxUnit,
|
||||||
|
smallest = 's',
|
||||||
|
unit = {},
|
||||||
|
}: IDurationOptions = {}) {
|
||||||
|
const odict = this.toOrderedDict()
|
||||||
|
const smallestIndex = odict.map(([k]) => k).indexOf(smallest)
|
||||||
|
const filteredDict = odict.filter(([, v], i) => v && i >= smallestIndex)
|
||||||
|
|
||||||
|
const str = filteredDict
|
||||||
|
.slice(granularity ? filteredDict.length - granularity : 0)
|
||||||
|
.reverse()
|
||||||
|
.slice(0, maxUnit)
|
||||||
|
.map(([k, v]) => `${v.toLocaleString()}${unit[k] || k}`)
|
||||||
|
.join(' ')
|
||||||
|
|
||||||
|
if (sign) {
|
||||||
|
return this.sign + str
|
||||||
|
}
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
private _parse(
|
||||||
|
current: (d: Date) => number,
|
||||||
|
upper?: {
|
||||||
|
get: (d: Date) => number
|
||||||
|
set: (d: Date, v: number) => void
|
||||||
|
inc: (d: Date) => number
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
let a = current(this._dates[1]) - current(this._dates[0])
|
||||||
|
|
||||||
|
if (upper) {
|
||||||
|
while (a < 0) {
|
||||||
|
upper.set(this._dates[1], upper.get(this._dates[1]) - 1)
|
||||||
|
this._dates[1] = new Date(this._dates[1])
|
||||||
|
|
||||||
|
a += upper.inc(this._dates[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date adding functions
|
||||||
|
*/
|
||||||
|
export function addDate(d: Date): Record<DurationUnit, (n: number) => Date> {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Milliseconds
|
||||||
|
*/
|
||||||
|
ms: (n) => {
|
||||||
|
d.setMilliseconds(d.getMilliseconds() + n)
|
||||||
|
return new Date(d)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Seconds
|
||||||
|
*/
|
||||||
|
s: (n) => {
|
||||||
|
d.setSeconds(d.getSeconds() + n)
|
||||||
|
return new Date(d)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Minutes
|
||||||
|
*/
|
||||||
|
min: (n) => {
|
||||||
|
d.setMinutes(d.getMinutes() + n)
|
||||||
|
return new Date(d)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Hours
|
||||||
|
*/
|
||||||
|
h: (n) => {
|
||||||
|
d.setHours(d.getHours() + n)
|
||||||
|
return new Date(d)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Date
|
||||||
|
*/
|
||||||
|
d: (n) => {
|
||||||
|
d.setDate(d.getDate() + n)
|
||||||
|
return new Date(d)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Weeks
|
||||||
|
*/
|
||||||
|
w: (n) => {
|
||||||
|
d.setDate(d.getDate() + n * 7)
|
||||||
|
return new Date(d)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Months
|
||||||
|
*/
|
||||||
|
mo: (n) => {
|
||||||
|
d.setMonth(d.getMonth() + n)
|
||||||
|
return new Date(d)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Years
|
||||||
|
*/
|
||||||
|
y: (n) => {
|
||||||
|
d.setFullYear(d.getFullYear() + n)
|
||||||
|
return new Date(d)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import 'vue-context/dist/css/vue-context.css'
|
||||||
|
|
||||||
|
import Vue from 'vue'
|
||||||
|
import VueContext from 'vue-context'
|
||||||
|
|
||||||
|
Vue.component('VueContext', VueContext)
|
||||||
+45
-32
@@ -1,4 +1,5 @@
|
|||||||
import { actionTree, getAccessorType, mutationTree } from 'typed-vuex'
|
import { actionTree, getAccessorType, mutationTree } from 'typed-vuex'
|
||||||
|
|
||||||
import { api } from '~/assets/api'
|
import { api } from '~/assets/api'
|
||||||
import { jsonClone } from '~/assets/util'
|
import { jsonClone } from '~/assets/util'
|
||||||
|
|
||||||
@@ -29,6 +30,24 @@ export const state = () => ({
|
|||||||
identifier: '',
|
identifier: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const SET_ALL_TABS = (
|
||||||
|
s: ReturnType<typeof state>,
|
||||||
|
o: {
|
||||||
|
tabs: ITab[]
|
||||||
|
activeTab: number
|
||||||
|
} = s
|
||||||
|
) => {
|
||||||
|
localStorage.setItem(
|
||||||
|
TAB_SETTINGS,
|
||||||
|
JSON.stringify({
|
||||||
|
tabs: o.tabs,
|
||||||
|
activeTabs: o.activeTab,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
s.tabs = jsonClone(o.tabs)
|
||||||
|
s.activeTab = jsonClone(o.activeTab)
|
||||||
|
}
|
||||||
|
|
||||||
export const mutations = mutationTree(state, {
|
export const mutations = mutationTree(state, {
|
||||||
SET_SETTINGS(state, settings: ISettings) {
|
SET_SETTINGS(state, settings: ISettings) {
|
||||||
state.settings = settings
|
state.settings = settings
|
||||||
@@ -36,26 +55,17 @@ export const mutations = mutationTree(state, {
|
|||||||
SET_IS_APP(state, isApp: boolean) {
|
SET_IS_APP(state, isApp: boolean) {
|
||||||
state.isApp = isApp
|
state.isApp = isApp
|
||||||
},
|
},
|
||||||
SET_ALL_TABS(
|
|
||||||
state,
|
|
||||||
o: {
|
|
||||||
tabs: ITab[]
|
|
||||||
activeTab: number
|
|
||||||
} = state
|
|
||||||
) {
|
|
||||||
localStorage.setItem(
|
|
||||||
TAB_SETTINGS,
|
|
||||||
JSON.stringify({
|
|
||||||
tabs: o.tabs,
|
|
||||||
activeTabs: o.activeTab,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
state.tabs = jsonClone(o.tabs)
|
|
||||||
state.activeTab = jsonClone(o.activeTab)
|
|
||||||
},
|
|
||||||
SET_TAB_TITLE(state, { i, title }: { i: number; title: string }) {
|
SET_TAB_TITLE(state, { i, title }: { i: number; title: string }) {
|
||||||
state.tabs[i].title = title
|
if (state.tabs[i]) {
|
||||||
this.SET_ALL_TABS(state)
|
state.tabs[i]!.title = title
|
||||||
|
SET_ALL_TABS(state)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
SET_ALL_TABS(state) {
|
||||||
|
const settings = localStorage.getItem(TAB_SETTINGS)
|
||||||
|
if (settings) {
|
||||||
|
Object.assign(state, JSON.parse(settings))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
ADD_TAB(
|
ADD_TAB(
|
||||||
state,
|
state,
|
||||||
@@ -90,7 +100,7 @@ export const mutations = mutationTree(state, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.activeTab = state.tabs.length - 1
|
state.activeTab = state.tabs.length - 1
|
||||||
this.SET_ALL_TABS(state)
|
SET_ALL_TABS(state)
|
||||||
},
|
},
|
||||||
DELETE_TAB(state, { i }: { i: number }) {
|
DELETE_TAB(state, { i }: { i: number }) {
|
||||||
state.tabs.splice(i, 1)
|
state.tabs.splice(i, 1)
|
||||||
@@ -99,15 +109,17 @@ export const mutations = mutationTree(state, {
|
|||||||
state.activeTab = state.tabs.length - 1
|
state.activeTab = state.tabs.length - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
this.SET_ALL_TABS(state)
|
SET_ALL_TABS(state)
|
||||||
},
|
},
|
||||||
SET_TAB_COMPONENT(state, { i, component }: { i: number; component: string }) {
|
SET_TAB_COMPONENT(state, { i, component }: { i: number; component: string }) {
|
||||||
state.tabs[i].component = component
|
if (state.tabs[i]) {
|
||||||
this.SET_ALL_TABS(state)
|
state.tabs[i]!.component = component
|
||||||
|
SET_ALL_TABS(state)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
SET_TAB_CURRENT(state, { i }: { i: number }) {
|
SET_TAB_CURRENT(state, { i }: { i: number }) {
|
||||||
state.activeTab = i
|
state.activeTab = i
|
||||||
this.SET_ALL_TABS(state)
|
SET_ALL_TABS(state)
|
||||||
},
|
},
|
||||||
SET_IDENTIFIER(state, name: string) {
|
SET_IDENTIFIER(state, name: string) {
|
||||||
state.identifier = name
|
state.identifier = name
|
||||||
@@ -117,16 +129,15 @@ export const mutations = mutationTree(state, {
|
|||||||
export const actions = actionTree(
|
export const actions = actionTree(
|
||||||
{ state, mutations },
|
{ state, mutations },
|
||||||
{
|
{
|
||||||
async nuxtServerInit({ dispatch, commit }) {
|
async nuxtServerInit({ commit }) {
|
||||||
await dispatch('updateSetings')
|
commit('SET_ALL_TABS')
|
||||||
|
|
||||||
const settings = localStorage.getItem(TAB_SETTINGS)
|
|
||||||
if (settings) commit('SET_ALL_TABS', JSON.parse(settings))
|
|
||||||
},
|
},
|
||||||
async updateSettings({ commit }) {
|
async updateSettings({ commit }) {
|
||||||
const r = await api.user_getSettings({
|
const r = await api
|
||||||
select: ['identifier', 'levelMin', 'level'],
|
.user_getSettings({
|
||||||
})
|
select: ['identifier', 'levelMin', 'level'],
|
||||||
|
})
|
||||||
|
.catch(() => null)
|
||||||
commit('SET_IS_APP', !!r)
|
commit('SET_IS_APP', !!r)
|
||||||
commit('SET_IDENTIFIER', r?.identifier || '')
|
commit('SET_IDENTIFIER', r?.identifier || '')
|
||||||
|
|
||||||
@@ -144,6 +155,8 @@ export const actions = actionTree(
|
|||||||
level: r?.level || null,
|
level: r?.level || null,
|
||||||
levelMin: r?.levelMin || null,
|
levelMin: r?.levelMin || null,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return !!r
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -908,6 +908,42 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7"
|
resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7"
|
||||||
integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==
|
integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==
|
||||||
|
|
||||||
|
"@fortawesome/fontawesome-common-types@^0.2.36":
|
||||||
|
version "0.2.36"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz#b44e52db3b6b20523e0c57ef8c42d315532cb903"
|
||||||
|
integrity sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg==
|
||||||
|
|
||||||
|
"@fortawesome/fontawesome-svg-core@^1.2.27", "@fortawesome/fontawesome-svg-core@^1.2.36":
|
||||||
|
version "1.2.36"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz#4f2ea6f778298e0c47c6524ce2e7fd58eb6930e3"
|
||||||
|
integrity sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==
|
||||||
|
dependencies:
|
||||||
|
"@fortawesome/fontawesome-common-types" "^0.2.36"
|
||||||
|
|
||||||
|
"@fortawesome/free-brands-svg-icons@^5.15.4":
|
||||||
|
version "5.15.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.4.tgz#ec8a44dd383bcdd58aa7d1c96f38251e6fec9733"
|
||||||
|
integrity sha512-f1witbwycL9cTENJegcmcZRYyawAFbm8+c6IirLmwbbpqz46wyjbQYLuxOc7weXFXfB7QR8/Vd2u5R3q6JYD9g==
|
||||||
|
dependencies:
|
||||||
|
"@fortawesome/fontawesome-common-types" "^0.2.36"
|
||||||
|
|
||||||
|
"@fortawesome/free-solid-svg-icons@^5.15.4":
|
||||||
|
version "5.15.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz#2a68f3fc3ddda12e52645654142b9e4e8fbb6cc5"
|
||||||
|
integrity sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==
|
||||||
|
dependencies:
|
||||||
|
"@fortawesome/fontawesome-common-types" "^0.2.36"
|
||||||
|
|
||||||
|
"@fortawesome/vue-fontawesome@^0.1.9":
|
||||||
|
version "0.1.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fortawesome/vue-fontawesome/-/vue-fontawesome-0.1.10.tgz#eeeec1e4e8850bed0468f938292b06cda793bf34"
|
||||||
|
integrity sha512-b2+SLF31h32LSepVcXe+BQ63yvbq5qmTCy4KfFogCYm2bn68H5sDWUnX+U7MBqnM2aeEk9M7xSoqGnu+wSdY6w==
|
||||||
|
|
||||||
|
"@fortawesome/vue-fontawesome@^2.0.6":
|
||||||
|
version "2.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fortawesome/vue-fontawesome/-/vue-fontawesome-2.0.6.tgz#87e691ed87f28f4667238573a29743f543a087f6"
|
||||||
|
integrity sha512-V3vT3flY15AKbUS31aZOP12awQI3aAzkr2B1KnqcHLmwrmy51DW3pwyBczKdypV8QxBZ8U68Hl2XxK2nudTxpg==
|
||||||
|
|
||||||
"@gar/promisify@^1.0.1":
|
"@gar/promisify@^1.0.1":
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210"
|
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210"
|
||||||
@@ -1165,7 +1201,7 @@
|
|||||||
rc9 "^1.2.0"
|
rc9 "^1.2.0"
|
||||||
std-env "^2.3.0"
|
std-env "^2.3.0"
|
||||||
|
|
||||||
"@nuxt/types@^2.15.7":
|
"@nuxt/types@^2.15.8":
|
||||||
version "2.15.8"
|
version "2.15.8"
|
||||||
resolved "https://registry.yarnpkg.com/@nuxt/types/-/types-2.15.8.tgz#1249de448f68169fe17e9379ee7b5caa0eb336b0"
|
resolved "https://registry.yarnpkg.com/@nuxt/types/-/types-2.15.8.tgz#1249de448f68169fe17e9379ee7b5caa0eb336b0"
|
||||||
integrity sha512-zBAG5Fy+SIaZIerOVF1vxy1zz16ZK07QSbsuQAjdtEFlvr+vKK+0AqCv8r8DBY5IVqdMIaw5FgNUz5py0xWdPg==
|
integrity sha512-zBAG5Fy+SIaZIerOVF1vxy1zz16ZK07QSbsuQAjdtEFlvr+vKK+0AqCv8r8DBY5IVqdMIaw5FgNUz5py0xWdPg==
|
||||||
@@ -1302,6 +1338,21 @@
|
|||||||
webpack-node-externals "^3.0.0"
|
webpack-node-externals "^3.0.0"
|
||||||
webpackbar "^4.0.0"
|
webpackbar "^4.0.0"
|
||||||
|
|
||||||
|
"@nuxtjs/fontawesome@^1.1.2":
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nuxtjs/fontawesome/-/fontawesome-1.1.2.tgz#0add6519095b392bdffb6e3ad40f3026d20f5c44"
|
||||||
|
integrity sha512-QAfo7hdc6hiCOohdR861oNQ+riKW/kD22bYyvaC++xXiiC1hBQcrRQ6xXd5gln+6SKCwT09+C4kGjzTgrwtr7w==
|
||||||
|
dependencies:
|
||||||
|
"@fortawesome/fontawesome-svg-core" "^1.2.27"
|
||||||
|
"@fortawesome/vue-fontawesome" "^0.1.9"
|
||||||
|
|
||||||
|
"@nuxtjs/proxy@^2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nuxtjs/proxy/-/proxy-2.1.0.tgz#fa7715a11d237fa1273503c4e9e137dd1bf5575b"
|
||||||
|
integrity sha512-/qtoeqXgZ4Mg6LRg/gDUZQrFpOlOdHrol/vQYMnKu3aN3bP90UfOUB3QSDghUUK7OISAJ0xp8Ld78aHyCTcKCQ==
|
||||||
|
dependencies:
|
||||||
|
http-proxy-middleware "^1.0.6"
|
||||||
|
|
||||||
"@nuxtjs/pwa@^3.3.5":
|
"@nuxtjs/pwa@^3.3.5":
|
||||||
version "3.3.5"
|
version "3.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/@nuxtjs/pwa/-/pwa-3.3.5.tgz#db7c905536ebe8a464a347b6ae3215810642c044"
|
resolved "https://registry.yarnpkg.com/@nuxtjs/pwa/-/pwa-3.3.5.tgz#db7c905536ebe8a464a347b6ae3215810642c044"
|
||||||
@@ -1470,6 +1521,13 @@
|
|||||||
"@types/relateurl" "*"
|
"@types/relateurl" "*"
|
||||||
"@types/uglify-js" "*"
|
"@types/uglify-js" "*"
|
||||||
|
|
||||||
|
"@types/http-proxy@^1.17.5":
|
||||||
|
version "1.17.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.7.tgz#30ea85cc2c868368352a37f0d0d3581e24834c6f"
|
||||||
|
integrity sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8":
|
"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8":
|
||||||
version "7.0.9"
|
version "7.0.9"
|
||||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
|
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
|
||||||
@@ -2121,10 +2179,10 @@ autoprefixer@^9.6.1:
|
|||||||
postcss "^7.0.32"
|
postcss "^7.0.32"
|
||||||
postcss-value-parser "^4.1.0"
|
postcss-value-parser "^4.1.0"
|
||||||
|
|
||||||
axios@^0.23.0:
|
axios@^0.24.0:
|
||||||
version "0.23.0"
|
version "0.24.0"
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.23.0.tgz#b0fa5d0948a8d1d75e3d5635238b6c4625b05149"
|
resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
|
||||||
integrity sha512-NmvAE4i0YAv5cKq8zlDoPd1VLKAqX5oLuZKs8xkJa4qi6RGn0uhCYFjWtHHC9EM/MwOwYWOs53W+V0aqEXq1sg==
|
integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects "^1.14.4"
|
follow-redirects "^1.14.4"
|
||||||
|
|
||||||
@@ -2356,10 +2414,10 @@ browserslist@*, browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.16.6,
|
|||||||
node-releases "^2.0.1"
|
node-releases "^2.0.1"
|
||||||
picocolors "^1.0.0"
|
picocolors "^1.0.0"
|
||||||
|
|
||||||
buefy@^0.9.10:
|
buefy@^0.9.11:
|
||||||
version "0.9.10"
|
version "0.9.11"
|
||||||
resolved "https://registry.yarnpkg.com/buefy/-/buefy-0.9.10.tgz#17f64ee1ba43a145d1d3c56f45cba95e4e2975fa"
|
resolved "https://registry.yarnpkg.com/buefy/-/buefy-0.9.11.tgz#69ab7f46e4f172d43247916f770f29764f9e0931"
|
||||||
integrity sha512-xXEoy/NTgBNiIfBTCdHi2Vu5SJJdB046py6ekUvYuUgYwRvulySZksdecVNNWdfEVU8iD4esZaRbTLwCegFcVQ==
|
integrity sha512-WP32SiaM9WVxDtzgdiq7V2zyIvn41NboPgluVqdB6OAi1/QhjO/63m6hd/jy6Vk8r+zuhIZD+aP9KlQ10EhxTQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
bulma "0.9.3"
|
bulma "0.9.3"
|
||||||
|
|
||||||
@@ -2894,10 +2952,10 @@ core-js@^2.6.5:
|
|||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||||
|
|
||||||
core-js@^3.15.1:
|
core-js@^3.19.0:
|
||||||
version "3.18.3"
|
version "3.19.0"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.18.3.tgz#86a0bba2d8ec3df860fefcc07a8d119779f01509"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.19.0.tgz#9e40098a9bc326c7e81b486abbd5e12b9d275176"
|
||||||
integrity sha512-tReEhtMReZaPFVw7dajMx0vlsz3oOb8ajgPoHVYGxr8ErnZ6PcYEvvmjGmXlfpnxpkYSdOQttjB+MvVbCGfvLw==
|
integrity sha512-L1TpFRWXZ76vH1yLM+z6KssLZrP8Z6GxxW4auoCj+XiViOzNPJCAuTIkn03BGdFe6Z5clX5t64wRIRypsZQrUg==
|
||||||
|
|
||||||
core-util-is@~1.0.0:
|
core-util-is@~1.0.0:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
@@ -3599,6 +3657,11 @@ etag@^1.8.1, etag@~1.8.1:
|
|||||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
||||||
|
|
||||||
|
eventemitter3@^4.0.0:
|
||||||
|
version "4.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||||
|
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||||
|
|
||||||
events@^3.0.0:
|
events@^3.0.0:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||||
@@ -3837,6 +3900,11 @@ flush-write-stream@^1.0.0:
|
|||||||
inherits "^2.0.3"
|
inherits "^2.0.3"
|
||||||
readable-stream "^2.3.6"
|
readable-stream "^2.3.6"
|
||||||
|
|
||||||
|
follow-redirects@^1.0.0:
|
||||||
|
version "1.14.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
|
||||||
|
integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
|
||||||
|
|
||||||
follow-redirects@^1.14.4:
|
follow-redirects@^1.14.4:
|
||||||
version "1.14.4"
|
version "1.14.4"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379"
|
||||||
@@ -4302,6 +4370,26 @@ http-errors@~1.7.2:
|
|||||||
statuses ">= 1.5.0 < 2"
|
statuses ">= 1.5.0 < 2"
|
||||||
toidentifier "1.0.0"
|
toidentifier "1.0.0"
|
||||||
|
|
||||||
|
http-proxy-middleware@^1.0.6:
|
||||||
|
version "1.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz#43700d6d9eecb7419bf086a128d0f7205d9eb665"
|
||||||
|
integrity sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==
|
||||||
|
dependencies:
|
||||||
|
"@types/http-proxy" "^1.17.5"
|
||||||
|
http-proxy "^1.18.1"
|
||||||
|
is-glob "^4.0.1"
|
||||||
|
is-plain-obj "^3.0.0"
|
||||||
|
micromatch "^4.0.2"
|
||||||
|
|
||||||
|
http-proxy@^1.18.1:
|
||||||
|
version "1.18.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
|
||||||
|
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
|
||||||
|
dependencies:
|
||||||
|
eventemitter3 "^4.0.0"
|
||||||
|
follow-redirects "^1.0.0"
|
||||||
|
requires-port "^1.0.0"
|
||||||
|
|
||||||
https-browserify@^1.0.0:
|
https-browserify@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||||
@@ -4658,6 +4746,11 @@ is-plain-obj@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
|
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
|
||||||
integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
|
integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
|
||||||
|
|
||||||
|
is-plain-obj@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7"
|
||||||
|
integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==
|
||||||
|
|
||||||
is-plain-object@^2.0.3, is-plain-object@^2.0.4:
|
is-plain-object@^2.0.3, is-plain-object@^2.0.4:
|
||||||
version "2.0.4"
|
version "2.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
|
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
|
||||||
@@ -5158,7 +5251,7 @@ micromatch@^3.1.10, micromatch@^3.1.4:
|
|||||||
snapdragon "^0.8.1"
|
snapdragon "^0.8.1"
|
||||||
to-regex "^3.0.2"
|
to-regex "^3.0.2"
|
||||||
|
|
||||||
micromatch@^4.0.0, micromatch@^4.0.4:
|
micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4:
|
||||||
version "4.0.4"
|
version "4.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
||||||
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
||||||
@@ -5517,12 +5610,12 @@ num2fraction@^1.2.2:
|
|||||||
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
|
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
|
||||||
integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
|
integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
|
||||||
|
|
||||||
nuxt-buefy@^0.4.8:
|
nuxt-buefy@^0.4.11:
|
||||||
version "0.4.10"
|
version "0.4.11"
|
||||||
resolved "https://registry.yarnpkg.com/nuxt-buefy/-/nuxt-buefy-0.4.10.tgz#7e091ebee5c7dd2bf9de46a3b7a36a3a4d0d4fba"
|
resolved "https://registry.yarnpkg.com/nuxt-buefy/-/nuxt-buefy-0.4.11.tgz#38a4d2a3abae05c64034d005e46728cfd694fa25"
|
||||||
integrity sha512-Kk/QrNXUrIe3/iPecb0v1OmcZWfdihioEuPtqW4OUfaDDPrVUdfPPRKLMHNgy1OPxDEGSor/h3zMr23d9/0Nyw==
|
integrity sha512-mld92vqY5uo+aQp4E8OnVE0abXPgf5t+k4ckmsMgYGfn0T3pDqJq7O4JLELxfBxfmBxmwce8lJ6ZaJ2GxCNaWQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
buefy "^0.9.10"
|
buefy "^0.9.11"
|
||||||
|
|
||||||
nuxt-property-decorator@^2.9.1:
|
nuxt-property-decorator@^2.9.1:
|
||||||
version "2.9.1"
|
version "2.9.1"
|
||||||
@@ -5542,7 +5635,7 @@ nuxt-typed-vuex@^0.2.0:
|
|||||||
typed-vuex "0.2.0"
|
typed-vuex "0.2.0"
|
||||||
upath "^2.0.1"
|
upath "^2.0.1"
|
||||||
|
|
||||||
nuxt@^2.15.7:
|
nuxt@^2.15.8:
|
||||||
version "2.15.8"
|
version "2.15.8"
|
||||||
resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.15.8.tgz#946cba46bdaaf0e3918aa27fd9ea0fed8ed303b0"
|
resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.15.8.tgz#946cba46bdaaf0e3918aa27fd9ea0fed8ed303b0"
|
||||||
integrity sha512-ceK3qLg/Baj7J8mK9bIxqw9AavrF+LXqwYEreBdY/a4Sj8YV4mIvhqea/6E7VTCNNGvKT2sJ/TTJjtfQ597lTA==
|
integrity sha512-ceK3qLg/Baj7J8mK9bIxqw9AavrF+LXqwYEreBdY/a4Sj8YV4mIvhqea/6E7VTCNNGvKT2sJ/TTJjtfQ597lTA==
|
||||||
@@ -6600,7 +6693,7 @@ prettier@^1.18.2:
|
|||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
|
||||||
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
|
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
|
||||||
|
|
||||||
prettier@^2.3.2:
|
prettier@^2.4.1:
|
||||||
version "2.4.1"
|
version "2.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
|
||||||
integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
|
integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
|
||||||
@@ -6925,6 +7018,11 @@ repeat-string@^1.6.1:
|
|||||||
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
||||||
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
|
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
|
||||||
|
|
||||||
|
requires-port@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||||
|
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||||
|
|
||||||
resolve-from@^3.0.0:
|
resolve-from@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
|
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
|
||||||
@@ -7062,10 +7160,10 @@ sass-loader@10.1.1, sass-loader@~10.1.1:
|
|||||||
schema-utils "^3.0.0"
|
schema-utils "^3.0.0"
|
||||||
semver "^7.3.2"
|
semver "^7.3.2"
|
||||||
|
|
||||||
sass@^1.43.3:
|
sass@^1.43.4:
|
||||||
version "1.43.3"
|
version "1.43.4"
|
||||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.43.3.tgz#aa16a69131b84f0cd23189a242571e8905f1ce43"
|
resolved "https://registry.yarnpkg.com/sass/-/sass-1.43.4.tgz#68c7d6a1b004bef49af0d9caf750e9b252105d1f"
|
||||||
integrity sha512-BJnLngqWpMeS65UvlYYEuCb3/fLxDxhHtOB/gWPxs6NKrslTxGt3ZxwIvOe/0Jm4tWwM/+tIpE3wj4dLEhPDeQ==
|
integrity sha512-/ptG7KE9lxpGSYiXn7Ar+lKOv37xfWsZRtFYal2QHNigyVQDx685VFT/h7ejVr+R8w7H4tmUgtulsKl5YpveOg==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar ">=3.0.0 <4.0.0"
|
chokidar ">=3.0.0 <4.0.0"
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user