asciibird/src/store/index.js

578 lines
18 KiB
JavaScript
Raw Normal View History

2020-12-19 00:14:06 +00:00
import Vue from 'vue';
2021-08-04 03:21:06 +00:00
import Vuex from 'vuex';
2021-01-23 02:50:32 +00:00
import VuexPersistence from 'vuex-persist';
import LZString from 'lz-string';
2021-08-05 05:38:01 +00:00
import {
blockWidth,
blockHeight,
cyrb53,
2021-08-14 06:41:42 +00:00
getBlocksWidth,
create2DArray,
emptyBlock,
maxBrushHistory,
maxUndoHistory,
mergeLayers
2021-08-05 05:38:01 +00:00
} from "../ascii";
2020-12-19 00:14:06 +00:00
Vue.use(Vuex);
const vuexLocal = new VuexPersistence({
2021-01-23 02:50:32 +00:00
storage: window.localStorage,
});
2020-12-19 00:14:06 +00:00
export default new Vuex.Store({
2021-03-31 23:29:55 +00:00
2020-12-19 00:14:06 +00:00
state: {
2021-04-24 00:42:33 +00:00
modalState: {
newAscii: false,
editAscii: false,
pasteAscii: false,
2021-04-24 00:42:33 +00:00
},
2021-09-04 01:13:28 +00:00
isKeyboardDisabled: false,
2021-03-31 23:29:55 +00:00
// The various options of ASCIIBIRD will eventually
// end up in its own modal I guess
options: {
defaultBg: 1,
defaultFg: 0,
2021-03-31 23:29:55 +00:00
},
// Current tab user is viewing
tab: 0,
// asciibirdMeta holds all of the ASCII information for all the tabs
2021-01-09 01:57:48 +00:00
asciibirdMeta: [],
2021-02-06 01:22:16 +00:00
toolbarState: {
2021-03-29 05:10:31 +00:00
currentColourFg: 0,
currentColourBg: 1,
2021-03-20 03:45:10 +00:00
isChoosingFg: false,
isChoosingBg: false,
2021-03-29 08:21:23 +00:00
isChoosingChar: false,
2021-04-17 00:12:02 +00:00
brushSizeWidth: 1,
brushSizeHeight: 1,
2021-05-01 02:17:49 +00:00
// square, circle, cross
brushSizeType: 'square',
2021-03-20 03:45:10 +00:00
selectedFg: 0,
selectedBg: 1,
selectedChar: ' ',
2021-03-13 03:30:58 +00:00
isUpdating: false,
2021-04-02 02:07:49 +00:00
currentTool: 0,
2021-03-30 08:36:53 +00:00
targetingFg: true,
2021-03-27 04:16:15 +00:00
targetingBg: true,
2021-03-30 08:36:53 +00:00
targetingChar: true,
2021-07-31 02:12:11 +00:00
mirrorX: false,
mirrorY: false,
x: blockWidth * 2,
y: blockHeight * 2,
2021-08-14 06:41:42 +00:00
h: blockHeight * 19,
w: blockWidth * 25,
draggable: true,
2021-08-14 06:41:42 +00:00
updateBrush: true,
gridView: false,
},
debugPanelState: {
2021-08-14 06:41:42 +00:00
x: blockWidth * 130,
y: blockHeight * 2,
h: blockHeight * 50,
w: blockWidth * 25,
visible: false,
},
blockSizeMultiplier: 1,
2021-05-01 02:17:49 +00:00
brushBlocks: [],
2021-08-06 04:00:21 +00:00
brushHistory: [],
selectBlocks: [],
2021-08-06 04:00:21 +00:00
brushLibrary: [],
2021-08-07 02:41:47 +00:00
brushLibraryState: {
x: blockWidth * 130,
y: blockHeight * 23,
h: blockHeight * 25,
2021-08-14 06:41:42 +00:00
w: blockWidth * 35,
2021-08-07 02:41:47 +00:00
visible: true,
tab: 0,
2021-08-07 02:41:47 +00:00
},
2021-08-14 06:41:42 +00:00
brushPreviewState: {
x: blockWidth * 2,
y: blockHeight * 22,
h: blockHeight * 19,
w: blockWidth * 25,
visible: true,
},
layersLibraryState: {
x: blockWidth * 130,
y: blockHeight * 2,
h: blockHeight * 19,
w: blockWidth * 35,
visible: true,
},
2020-12-19 00:14:06 +00:00
},
mutations: {
changeState(state, payload) {
2021-04-03 03:13:03 +00:00
Object.assign(state, payload);
},
changeTab(state, payload) {
2021-02-13 01:51:01 +00:00
state.tab = payload;
2021-08-12 02:22:29 +00:00
document.title = `asciibird - ${state.asciibirdMeta[payload].title}`;
},
changeDebugPanelState(state, payload) {
2021-04-03 03:13:03 +00:00
state.debugPanelState = payload;
},
toggleDebugPanel(state, payload) {
state.debugPanelState.visible = payload;
},
2021-08-07 02:41:47 +00:00
changeBrushLibraryState(state, payload) {
state.brushLibraryState = payload;
},
2021-08-14 06:41:42 +00:00
changeBrushPreviewState(state, payload) {
state.brushPreviewState = payload;
},
2021-08-07 02:41:47 +00:00
toggleBrushLibrary(state, payload) {
state.brushLibraryState.visible = payload;
},
changeToolBarState(state, payload) {
2021-04-03 03:13:03 +00:00
state.toolbarState.x = payload.x;
state.toolbarState.y = payload.y;
2021-04-24 00:20:11 +00:00
state.toolbarState.w = payload.w;
state.toolbarState.h = payload.h;
2021-04-03 03:13:03 +00:00
},
changeToolBarDraggable(state, payload) {
state.toolbarState.draggable = payload;
},
changeLayersLibraryState(state, payload) {
state.layersLibraryState = payload;
},
2021-04-03 03:13:03 +00:00
changeAsciiWidthHeight(state, payload) {
2021-08-15 00:15:36 +00:00
state.asciibirdMeta[state.tab].blocks = LZString.compressToUTF16(JSON.stringify(
payload.layers));
},
changeAsciiCanvasState(state, payload) {
2021-04-03 03:13:03 +00:00
state.asciibirdMeta[state.tab].x = payload.x;
state.asciibirdMeta[state.tab].y = payload.y;
},
2021-03-29 05:10:31 +00:00
changeColourFg(state, payload) {
state.toolbarState.currentColourFg = payload;
2021-03-31 23:29:55 +00:00
state.toolbarState.isUpdating = false;
state.toolbarState.isChoosingFg = false;
2021-03-13 03:30:58 +00:00
},
2021-03-29 05:10:31 +00:00
changeColourBg(state, payload) {
state.toolbarState.currentColourBg = payload;
2021-03-31 23:29:55 +00:00
state.toolbarState.isUpdating = false;
state.toolbarState.isChoosingBg = false;
2021-02-06 01:22:16 +00:00
},
2021-03-29 08:21:23 +00:00
changeChar(state, payload) {
state.toolbarState.selectedChar = payload;
2021-03-31 23:29:55 +00:00
state.toolbarState.isUpdating = false;
state.toolbarState.isChoosingChar = false;
2021-03-29 08:21:23 +00:00
},
2021-02-06 01:22:16 +00:00
changeTool(state, payload) {
2021-02-13 01:51:01 +00:00
state.toolbarState.currentTool = payload;
2021-02-06 01:22:16 +00:00
},
2021-03-29 01:03:42 +00:00
changeIsUpdatingFg(state, payload) {
2021-03-31 23:29:55 +00:00
state.toolbarState.isChoosingFg = payload;
2021-03-29 01:03:42 +00:00
},
changeIsUpdatingBg(state, payload) {
2021-03-31 23:29:55 +00:00
state.toolbarState.isChoosingBg = payload;
2021-03-29 01:03:42 +00:00
},
2021-03-29 08:21:23 +00:00
changeIsUpdatingChar(state, payload) {
2021-03-31 23:29:55 +00:00
state.toolbarState.isChoosingChar = payload;
2021-03-29 08:21:23 +00:00
},
2021-03-27 02:07:33 +00:00
changeTargetingFg(state, payload) {
2021-03-31 23:29:55 +00:00
state.toolbarState.targetingFg = payload;
2021-03-27 02:07:33 +00:00
},
changeTargetingBg(state, payload) {
2021-03-31 23:29:55 +00:00
state.toolbarState.targetingBg = payload;
2021-03-27 02:07:33 +00:00
},
2021-03-29 08:21:23 +00:00
changeTargetingChar(state, payload) {
state.toolbarState.targetingChar = payload;
2021-03-27 02:07:33 +00:00
},
2020-12-19 01:27:50 +00:00
newAsciibirdMeta(state, payload) {
2021-02-06 01:57:35 +00:00
state.asciibirdMeta.push(payload);
2021-08-04 03:21:06 +00:00
state.tab = state.asciibirdMeta.length - 1;
2021-08-12 02:22:29 +00:00
document.title = `asciibird - ${state.asciibirdMeta[state.tab].title}`;
2021-02-06 01:57:35 +00:00
},
2021-03-20 03:45:10 +00:00
updateToolBarState(state, payload) {
2021-03-31 23:29:55 +00:00
state.toolbarState = payload;
},
2021-07-31 02:12:11 +00:00
updateMirror(state, payload) {
state.toolbarState.mirrorX = payload.x;
state.toolbarState.mirrorY = payload.y;
},
2021-05-15 01:52:20 +00:00
updateAsciiBlocks(state, payload, skipUndo = false) {
if (state.asciibirdMeta[state.tab].history.length >= maxUndoHistory) {
2021-08-19 01:42:33 +00:00
state.asciibirdMeta[state.tab].history.shift()
}
2021-05-15 01:52:20 +00:00
if (!skipUndo) {
2021-08-04 03:21:06 +00:00
state.asciibirdMeta[state.tab].history.push(state.asciibirdMeta[state.tab].blocks);
2021-05-15 01:52:20 +00:00
}
2021-08-14 06:41:42 +00:00
let tempLayers = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
.blocks))
tempLayers[state.asciibirdMeta[state.tab].selectedLayer].data = payload
state.asciibirdMeta[state.tab].blocks = LZString.compressToUTF16(JSON.stringify(
tempLayers));
state.asciibirdMeta[state.tab].redo = [];
2021-04-02 04:43:11 +00:00
},
2021-08-14 06:41:42 +00:00
//
// LAYERS
//
addLayer(state) {
let tempLayers = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
.blocks))
let width = tempLayers[0].width;
let height = tempLayers[0].height;
let newBlocksArray = create2DArray(height);
2021-08-14 06:41:42 +00:00
// Push all the default ASCII blocks
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
2021-08-14 06:41:42 +00:00
newBlocksArray[y].push({
...emptyBlock,
});
}
}
2021-08-14 09:09:36 +00:00
tempLayers.push({
2021-08-14 06:41:42 +00:00
label: 'Layer ' + Number.parseInt(tempLayers.length),
visible: true,
data: [...newBlocksArray],
width: width,
height: height
2021-08-14 06:41:42 +00:00
})
state.asciibirdMeta[state.tab].blocks = LZString.compressToUTF16(JSON.stringify(
tempLayers));
},
mergeAllLayers(state) {
let tempLayers = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
.blocks))
let width = tempLayers[0].width;
let height = tempLayers[0].height;
2021-08-28 03:20:59 +00:00
let label = tempLayers[state.asciibirdMeta[state.tab].selectedLayer].label;
let mergedLayers = [{
visible: true,
width: width,
height: height,
label: label,
data: mergeLayers()
}];
state.asciibirdMeta[state.tab].selectedLayer = 0;
state.asciibirdMeta[state.tab].blocks = LZString.compressToUTF16(JSON.stringify(
mergedLayers));
},
2021-08-14 06:41:42 +00:00
changeLayer(state, payload) {
state.asciibirdMeta[state.tab].selectedLayer = payload
},
toggleLayer(state, payload) {
let tempLayers = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
.blocks))
tempLayers[payload].visible = !tempLayers[payload].visible
state.asciibirdMeta[state.tab].blocks = LZString.compressToUTF16(JSON.stringify(
tempLayers));
},
removeLayer(state, payload) {
let tempLayers = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
.blocks))
if (tempLayers.length > 1) {
tempLayers.splice(payload, 1)
2021-08-17 00:24:41 +00:00
// Automatically select the next best layer to avoid bugs
if (tempLayers[payload + 1]) {
state.asciibirdMeta[state.tab].selectedLayer = payload + 1
} else if (tempLayers[payload - 1]) {
state.asciibirdMeta[state.tab].selectedLayer = payload - 1
} else if (tempLayers[0]) {
state.asciibirdMeta[state.tab].selectedLayer = 0
}
2021-08-14 06:41:42 +00:00
state.asciibirdMeta[state.tab].blocks = LZString.compressToUTF16(JSON.stringify(
tempLayers));
}
},
downLayer(state, payload) {
let tempLayers = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
.blocks))
if (tempLayers[payload + 1]) {
let swap1 = tempLayers[payload + 1];
let swap = tempLayers[payload];
tempLayers[payload + 1] = swap
tempLayers[payload] = swap1
state.asciibirdMeta[state.tab].blocks = LZString.compressToUTF16(JSON.stringify(
tempLayers));
}
},
upLayer(state, payload) {
let tempLayers = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
.blocks))
if (tempLayers[payload - 1]) {
let swap1 = tempLayers[payload - 1];
let swap = tempLayers[payload];
tempLayers[payload - 1] = swap
tempLayers[payload] = swap1
state.asciibirdMeta[state.tab].blocks = LZString.compressToUTF16(JSON.stringify(
tempLayers));
}
},
updateLayerName(state, payload) {
let tempLayers = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
.blocks))
if (tempLayers[payload.key]) {
tempLayers[payload.key].label = payload.label;
state.asciibirdMeta[state.tab].blocks = LZString.compressToUTF16(JSON.stringify(
tempLayers));
}
2021-08-14 06:41:42 +00:00
},
// ASCII
updateAscii(state, payload) {
2021-08-04 03:21:06 +00:00
state.asciibirdMeta[state.tab] = payload;
},
2021-08-14 06:41:42 +00:00
// BLOCKS
2021-05-15 01:52:20 +00:00
undoBlocks(state) {
if (state.asciibirdMeta[state.tab].history.length > 1) {
2021-08-04 03:21:06 +00:00
state.asciibirdMeta[state.tab].blocks = state.asciibirdMeta[state.tab].history.pop();
2021-08-19 01:42:33 +00:00
state.asciibirdMeta[state.tab].redo.push(state.asciibirdMeta[state.tab].blocks);
}
},
redoBlocks(state) {
2021-08-03 04:59:12 +00:00
if (state.asciibirdMeta[state.tab].redo.length) {
2021-08-04 03:21:06 +00:00
const next = state.asciibirdMeta[state.tab].redo.pop();
state.asciibirdMeta[state.tab].blocks = next;
state.asciibirdMeta[state.tab].history.push(next);
}
2021-05-15 01:52:20 +00:00
},
2021-08-14 06:41:42 +00:00
//
// Toolbar
//
2021-04-17 00:12:02 +00:00
updateBrushSize(state, payload) {
state.toolbarState.brushSizeHeight = payload.brushSizeHeight;
state.toolbarState.brushSizeWidth = payload.brushSizeWidth;
2021-05-01 02:17:49 +00:00
state.toolbarState.brushSizeType = payload.brushSizeType;
},
brushBlocks(state, payload) {
2021-08-03 04:59:12 +00:00
state.brushBlocks = LZString.compressToUTF16(JSON.stringify(payload));
2021-04-17 00:12:02 +00:00
},
selectBlocks(state, payload) {
2021-08-03 04:59:12 +00:00
state.selectBlocks = LZString.compressToUTF16(JSON.stringify(payload));
},
toggleGridView(state, payload) {
2021-08-14 06:41:42 +00:00
state.toolbarState.gridView = payload;
},
2021-08-14 06:41:42 +00:00
toggleUpdateBrush(state, payload) {
state.toolbarState.updateBrush = payload;
},
flipRotateBlocks(state, payload) {
let tempBlocks = JSON.parse(LZString.decompressFromUTF16(state.brushBlocks))
let parsedBlocks = [];
let x = 0;
let y = 0;
2021-08-12 02:22:29 +00:00
switch (payload.type) {
case 'flip':
tempBlocks = tempBlocks.reverse()
2021-08-12 02:22:29 +00:00
for (y = 0; y < tempBlocks.length; y++) {
parsedBlocks[y] = tempBlocks[y];
for (x = 0; x < getBlocksWidth(tempBlocks); x++) {
parsedBlocks[y][x] = tempBlocks[y][x];
}
}
2021-08-12 02:22:29 +00:00
break;
case 'rotate':
for (y = 0; y < tempBlocks.length; y++) {
parsedBlocks[y] = tempBlocks[y].reverse();
for (x = 0; x < getBlocksWidth(tempBlocks); x++) {
parsedBlocks[y][x] = tempBlocks[y][x];
}
}
2021-08-12 02:22:29 +00:00
break;
}
state.brushBlocks = LZString.compressToUTF16(JSON.stringify(parsedBlocks));
},
// Brush Library
2021-08-06 04:00:21 +00:00
pushBrushHistory(state, payload) {
// Check and remove duplicate brushes based on hash value
console.log(state.brushHistory.length, maxBrushHistory)
if (state.brushHistory.length >= maxBrushHistory) {
state.brushHistory.pop();
}
let hashValue = cyrb53(JSON.stringify(payload))
state.brushHistory = state.brushHistory.filter(obj => obj.hash !== hashValue);
state.brushHistory.unshift({
blocks: LZString.compressToUTF16(JSON.stringify(payload)),
hash: hashValue
});
2021-08-06 04:00:21 +00:00
},
pushBrushLibrary(state, payload) {
// Check and remove duplicate brushes based on hash value
let hashValue = cyrb53(JSON.stringify(payload))
state.brushLibrary = state.brushLibrary.filter(obj => obj.hash !== hashValue);
state.brushLibrary.unshift({
blocks: LZString.compressToUTF16(JSON.stringify(payload)),
hash: hashValue
});
2021-08-06 04:00:21 +00:00
},
2021-08-06 11:00:35 +00:00
removeBrushLibrary(state, payload) {
let hashValue = cyrb53(JSON.stringify(payload))
state.brushLibrary = state.brushLibrary.filter(function (item) {
return item.hash !== hashValue
});
},
removeBrushHistory(state, payload) {
let hashValue = cyrb53(JSON.stringify(payload))
state.brushHistory = state.brushHistory.filter(function (item) {
return item.hash !== hashValue
});
},
2021-09-04 01:13:28 +00:00
toggleDisableKeyboard(state, payload = null) {
state.isKeyboardDisabled = (payload === null ? !state.isKeyboardDisabled : payload);
},
// Modals / Tabs
2021-04-24 00:42:33 +00:00
openModal(state, type) {
switch (type) {
case 'new-ascii':
state.modalState.newAscii = true;
2021-09-04 01:13:28 +00:00
state.isKeyboardDiasbled = true;
break;
2021-04-24 00:42:33 +00:00
case 'edit-ascii':
state.modalState.editAscii = true;
2021-09-04 01:13:28 +00:00
state.isKeyboardDisabled = true;
break;
2021-04-24 00:42:33 +00:00
case 'paste-ascii':
state.modalState.pasteAscii = true;
2021-09-04 01:13:28 +00:00
state.isKeyboardDisabled = true;
break;
}
},
closeModal(state, type) {
switch (type) {
case 'new-ascii':
state.modalState.newAscii = false;
2021-09-04 01:13:28 +00:00
state.isKeyboardDisabled = false;
break;
case 'edit-ascii':
state.modalState.editAscii = false;
2021-09-04 01:13:28 +00:00
state.isKeyboardDisabled = false;
break;
case 'paste-ascii':
state.modalState.pasteAscii = false;
2021-09-04 01:13:28 +00:00
state.isKeyboardDisabled = false;
break;
2021-04-24 00:42:33 +00:00
}
2021-08-04 03:21:06 +00:00
},
closeTab(state, tab) {
state.asciibirdMeta.splice(tab, 1);
// If we closed the tab we are viewing jump to the end tab
if (tab === state.tab) {
state.tab = state.asciibirdMeta.length - 1
}
2021-08-12 02:22:29 +00:00
if (state.asciibirdMeta.length) {
document.title = `asciibird - ${state.asciibirdMeta[state.tab].title}`;
} else {
document.title = `asciibird`
}
},
2021-02-06 01:57:35 +00:00
},
getters: {
state: (state) => state,
2021-04-24 00:42:33 +00:00
modalState: (state) => state.modalState,
options: (state) => state.options,
toolbarState: (state) => state.toolbarState,
debugPanel: (state) => state.debugPanelState,
currentTool: (state) => state.toolbarState.currentTool,
isTargettingBg: (state) => state.toolbarState.targetingBg,
isTargettingFg: (state) => state.toolbarState.targetingFg,
isTargettingChar: (state) => state.toolbarState.targetingChar,
currentFg: (state) => state.toolbarState.currentColourFg,
currentBg: (state) => state.toolbarState.currentColourBg,
2021-08-06 01:51:58 +00:00
currentChar: (state) => state.toolbarState.selectedChar,
2021-03-31 23:29:55 +00:00
currentTab: (state) => state.tab,
2021-08-04 03:21:06 +00:00
currentAscii: (state) => state.asciibirdMeta[state.tab] ?? false,
2021-08-14 06:41:42 +00:00
currentAsciiBlocks: (state) => {
let blocks = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[
2021-08-17 00:24:41 +00:00
state.tab].blocks)) || [];
2021-08-14 06:41:42 +00:00
2021-08-17 00:24:41 +00:00
return blocks[state.asciibirdMeta[state.tab].selectedLayer].data || []
2021-08-14 06:41:42 +00:00
},
currentAsciiLayers: (state) => {
let blocks = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[
state.tab].blocks));
return blocks
},
2021-08-28 03:20:59 +00:00
currentAsciiLayersWidthHeight: (state) => {
let blocks = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[
state.tab].blocks));
return {
width: blocks[0].width,
height: blocks[0].height,
}
},
2021-08-14 06:41:42 +00:00
selectedLayer: (state) => state.asciibirdMeta[state.tab].selectedLayer,
2021-03-31 23:29:55 +00:00
asciibirdMeta: (state) => state.asciibirdMeta,
nextTabValue: (state) => state.asciibirdMeta.length,
2021-04-17 00:12:02 +00:00
brushSizeHeight: (state) => state.toolbarState.brushSizeHeight,
brushSizeWidth: (state) => state.toolbarState.brushSizeWidth,
2021-05-01 02:17:49 +00:00
brushSizeType: (state) => state.toolbarState.brushSizeType,
2021-03-31 23:29:55 +00:00
blockSizeMultiplier: (state) => state.blockSizeMultiplier,
2021-08-06 04:00:21 +00:00
brushHistory: (state) => state.brushHistory,
brushLibrary: (state) => state.brushLibrary,
2021-08-07 02:41:47 +00:00
brushLibraryState: (state) => state.brushLibraryState,
2021-08-14 06:41:42 +00:00
brushPreviewState: (state) => state.brushPreviewState,
layersLibraryState: (state) => state.layersLibraryState,
2021-09-04 01:13:28 +00:00
isKeyboardDisabled: (state) => state.isKeyboardDisabled,
2021-08-04 03:21:06 +00:00
brushBlocks: (state) => JSON.parse(LZString.decompressFromUTF16(state.brushBlocks)) || [],
selectBlocks: (state) => JSON.parse(LZString.decompressFromUTF16(state.selectBlocks)) || [],
isModalOpen: (state) => {
2021-08-05 05:38:01 +00:00
for (const modalState in state.modalState) {
if (state.modalState[modalState] === true)
return true
}
return false
},
2020-12-19 00:14:06 +00:00
},
2020-12-19 01:27:50 +00:00
actions: {},
modules: {},
2021-01-23 02:50:32 +00:00
plugins: [vuexLocal.plugin],
2020-12-19 00:14:06 +00:00
});