Browse Source

VueApexCharts

master
yuriy0803 2 years ago
parent
commit
bbb5fd8855
  1. 82
      new-web/components/ExplorerLink.vue
  2. 2
      new-web/components/tables/Blocks.vue
  3. 2
      new-web/i18n/en.json
  4. 5
      new-web/nuxt.config.js
  5. 2
      new-web/package.json
  6. 49
      new-web/pages/blocks.vue
  7. 74
      new-web/pages/help.vue
  8. 165
      new-web/pages/index.vue
  9. 2
      new-web/params/networks.json
  10. 6
      new-web/plugins/apexcharts.js
  11. 5
      new-web/plugins/clipboard.js
  12. 5
      new-web/plugins/highlight.js
  13. 4
      new-web/plugins/notifications.js
  14. 4
      new-web/plugins/qrcode.js
  15. 4
      new-web/plugins/smoothreflow.js
  16. 29
      new-web/scss/_custom.scss
  17. 72
      new-web/yarn.lock

82
new-web/components/ExplorerLink.vue

@ -1,26 +1,22 @@
<template>
<a :href="formatUrl()" target="_blank">{{ formatHash(hash, clip) }}</a>
</template>
<script>
export default {
props: {
hash: {
// the tx or block hash/number
type: String,
default() {
return '0x0'
},
},
linkType: {
// link type (tx or block)
type: String,
default() {
return 'tx'
},
},
clip: {
// shorten inner url to (0x[clip][separator][clip]) characters. 0 = dont clip.
type: Number,
default() {
return 0
@ -33,7 +29,6 @@ export default {
},
},
config: {
// config
type: Object,
default() {
return {}
@ -42,81 +37,56 @@ export default {
},
methods: {
formatUrl() {
// see: https://github.com/ethereum/EIPs/pull/3091
// explorer.type
// expedition, blockscout, etherscan, etherchain, spectrum
// note, most of these are fairly similar however keeping all as options incase of future deviations.
const url = this.config.explorer.url
const type = this.config.explorer.type
let network = this.config.network
const symbol = this.config.symbol.toLowerCase()
let append = '/'
const { url, type, network, symbol } = this.config.explorer;
let append = '/';
// handle link type deviations
switch (this.linkType) {
case 'block':
if (type === 'blockscout') {
append = append + 'blocks/'
} else {
// etherscan, etherchain or expedition, spectrum
append = append + 'block/'
}
break
append = (type === 'blockscout') ? append + 'blocks/' : append + 'block/';
break;
case 'account':
if (type === 'etherchain') {
append = append + 'account/'
} else {
// etherscan, blockscout, expedition, spectrum
append = append + 'address/'
}
break
append = (type === 'etherchain') ? append + 'account/' : append + 'address/';
break;
case 'token':
if (type === 'blockscout') {
append = append + 'tokens/'
} else {
// etherscan, etherchain, expedition, spectrum
append = append + 'token/'
}
break
append = (type === 'blockscout') ? append + 'tokens/' : append + 'token/';
break;
case 'tx':
append = append + 'tx/' // yayyy conformity
break
append = append + 'tx/';
break;
default:
// o.O something very odd has occured O.o
// check your link-type argument, it should be:
// block, account, token, or tx
console.error('Invalid linkType argument. It should be one of: block, account, token, or tx');
return '';
}
// handle network deviations
switch (type) {
case 'expedition':
if (network === 'classic') {
network = 'mainnet'
network = 'mainnet';
}
append = append + this.hash + '?network=' + network
break
append = append + this.hash + '?network=' + network;
break;
case 'blockscout':
if (network === 'classic') {
network = 'mainnet'
network = 'mainnet';
}
append = '/' + symbol + '/' + network + append + this.hash
break
append = `/${symbol.toLowerCase()}/${network}${append}${this.hash}`;
break;
default:
append = append + this.hash
append = append + this.hash;
}
return url + append
return url + append;
},
formatHash(hash, len) {
if (hash === '0x0' || !hash) {
return 'N/A'
return 'N/A';
}
if (len > 0) {
const start = hash.substring(0, len + 2)
const end = hash.substring(hash.length - len)
return start + this.separator + end
const start = hash.substring(0, len + 2);
const end = hash.substring(hash.length - len);
return start + this.separator + end;
}
return hash
return hash;
},
},
}
};
</script>

2
new-web/components/tables/Blocks.vue

@ -92,7 +92,7 @@ export default {
align: 'start',
value: 'height',
},
{ text: this.$t('pages.blocks.blockHash'), value: 'hash' },
{ text: this.$t('pages.blocks.blockHash'), value: 'finder' },
{ text: this.$t('pages.blocks.timeFound'), value: 'timestamp' },
{ text: this.$t('pages.blocks.variance'), value: 'shares' },
{

2
new-web/i18n/en.json

@ -52,7 +52,7 @@
"blocksPerPage": "Blocks per page",
"search": "Search by number or hash",
"blockNumber": "Block Number",
"blockHash": "Block Hash",
"blockHash": "finder",
"timeFound": "Time Found",
"variance": "Variance",
"reward": "Reward",

5
new-web/nuxt.config.js

@ -2,9 +2,6 @@
import config from './params/config.json'
export default {
server: {
host: '192.168.8.169' // default: localhost sudo npm run dev
},
// Disable server-side rendering (https://go.nuxtjs.dev/ssr-mode)
ssr: false,
@ -25,7 +22,7 @@ export default {
//The dist folder is named dist by default but can be configured in your nuxt.config file.
generate: {
dir: '/var/www/etc3pool'
dir: '/var/www/testpool'
},
// Global CSS (https://go.nuxtjs.dev/config-css)

2
new-web/package.json

@ -28,6 +28,7 @@
"@nuxtjs/eslint-module": "^3.0.2",
"@nuxtjs/vuetify": "^1.12.1",
"@vue/test-utils": "^1.2.0",
"apexcharts": "^3.41.0",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.5.0",
@ -38,6 +39,7 @@
"husky": "^6.0.0",
"jest": "^26.5.0",
"prettier": "^2.4.1",
"vue-apexcharts": "^1.6.2",
"vue-jest": "^3.0.4"
}
}

49
new-web/pages/blocks.vue

@ -1,31 +1,23 @@
<template>
<v-row justify="center" align="center" no-gutters>
<v-col cols="12" class="pa-0">
<v-card tile flat style="margin-bottom: 1px solid #2e2e2e">
<v-card tile flat style="border-bottom: 1px solid #2e2e2e">
<v-simple-table>
<template #default>
<thead>
<tr>
<th class="text-left">
{{ $t('pages.blocks.blocks') }}
</th>
<th class="text-left">
{{ $t('pages.blocks.shares') }}
</th>
<th class="text-left">
{{ $t('pages.blocks.uncleRate') }}
</th>
<th class="text-left">
{{ $t('pages.blocks.orphanRate') }}
</th>
<th class="text-left">{{ $t('pages.blocks.blocks') }}</th>
<th class="text-left">{{ $t('pages.blocks.shares') }}</th>
<th class="text-left">{{ $t('pages.blocks.uncleRate') }}</th>
<th class="text-left">{{ $t('pages.blocks.orphanRate') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, key) in blocks.luck" :key="key">
<td>{{ key }}</td>
<td>{{ nf.format((item.luck * 100).toFixed(0)) }}%</td>
<td>{{ nf.format((item.uncleRate * 100).toFixed(0)) }}%</td>
<td>{{ nf.format((item.orphanRate * 100).toFixed(0)) }}%</td>
<td>{{ formatPercentage(item.luck) }}</td>
<td>{{ formatPercentage(item.uncleRate) }}</td>
<td>{{ formatPercentage(item.orphanRate) }}</td>
</tr>
</tbody>
</template>
@ -33,21 +25,9 @@
</v-card>
<v-card tile flat>
<v-tabs v-model="tab" background-color="transparent" grow>
<v-tab>{{ $t('pages.blocks.blocks')
}}<v-chip label small color="success" class="ml-2">{{
blocks.maturedTotal
}}</v-chip>
</v-tab>
<v-tab>{{ $t('pages.blocks.immature')
}}<v-chip label small color="warning" class="ml-2">{{
blocks.immatureTotal
}}</v-chip>
</v-tab>
<v-tab>{{ $t('pages.blocks.newBlocks')
}}<v-chip label small color="info" class="ml-2">{{
blocks.candidatesTotal
}}</v-chip>
</v-tab>
<v-tab>{{ $t('pages.blocks.blocks') }}<v-chip label small color="success" class="ml-2">{{ blocks.maturedTotal }}</v-chip></v-tab>
<v-tab>{{ $t('pages.blocks.immature') }}<v-chip label small color="warning" class="ml-2">{{ blocks.immatureTotal }}</v-chip></v-tab>
<v-tab>{{ $t('pages.blocks.newBlocks') }}<v-chip label small color="info" class="ml-2">{{ blocks.candidatesTotal }}</v-chip></v-tab>
</v-tabs>
<v-tabs-items v-model="tab">
<v-tab-item>
@ -75,7 +55,6 @@ export default {
data() {
return {
tab: null,
nf: new Intl.NumberFormat(this.locale, {}),
}
},
computed: {
@ -94,8 +73,10 @@ export default {
config() {
return this.$store.state.env
},
locale() {
return this.$i18n.locale
},
methods: {
formatPercentage(value) {
return (value * 100).toFixed(2) + '%'
},
},
}

74
new-web/pages/help.vue

@ -3,18 +3,12 @@
<v-col cols="12" sm="12" md="12">
<v-row no-gutters class="px-4">
<v-alert type="info" class="w-100 mb-0">
Change the address in the examples below to YOUR address before
starting your miner.
Change the address in the examples below to YOUR address before starting your miner.
</v-alert>
</v-row>
<v-row no-gutters class="px-4">
<v-col cols="12" sm="12" md="12">
<v-card
v-for="(miner, index) in miners"
:key="index"
tile
class="my-2"
>
<v-card v-for="(miner, index) in miners" :key="index" tile class="my-2">
<v-card-title class="headline ma-0">
{{ miner.title }}
<v-spacer />
@ -27,10 +21,7 @@
</v-card-title>
<v-card-text class="pa-0">
<article>
<nuxt-content
:document="miner"
:class="{ 'code-lightmode': !darkmode }"
/>
<nuxt-content :document="miner" :class="{ 'code-lightmode': !darkMode }" />
</article>
</v-card-text>
</v-card>
@ -41,64 +32,44 @@
</template>
<script>
// import config here as 'this' context within asyncData is not the 'this' we are looking for
import config from '~/params/config.json'
export default {
async asyncData({ $content }) {
const network = config.network
const pathPrefix = 'help/miners/' + network
const miners = []
const supportsClassic = [
'lolminer',
'nanominer',
'trex',
'nbminer',
'gminer',
'teamred',
'srbminer',
]
const pathPrefix = `help/miners/${network}`
const supportsClassic = ['lolminer', 'nanominer', 'trex', 'nbminer', 'gminer', 'teamred', 'srbminer']
const supportsMordor = ['lolminer', 'gminer']
const miners = []
if (network === 'mordor') {
for (const miner of supportsMordor) {
const doc = await $content(pathPrefix + '/' + miner).fetch()
miners.push(doc)
}
} else {
for (const miner of supportsClassic) {
const doc = await $content(pathPrefix + '/' + miner).fetch()
miners.push(doc)
}
}
// shuffle miners array to avoid an ordering bias
let currentIndex = miners.length
let temporaryValue
let randomIndex
// While there remain elements to shuffle...
while (currentIndex !== 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex)
currentIndex -= 1
const supportedMiners = network === 'mordor' ? supportsMordor : supportsClassic
// And swap it with the current element.
temporaryValue = miners[currentIndex]
miners[currentIndex] = miners[randomIndex]
miners[randomIndex] = temporaryValue
for (const miner of supportedMiners) {
const doc = await $content(`${pathPrefix}/${miner}`).fetch()
miners.push(doc)
}
shuffleArray(miners)
return {
miners,
}
},
computed: {
darkmode() {
darkMode() {
return this.$vuetify.theme.dark
},
},
}
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
const temp = array[i]
array[i] = array[j]
array[j] = temp
}
}
</script>
<style lang="scss" scoped>
@ -106,4 +77,3 @@ export default {
background-color: var(--v-secondary-base) !important;
}
</style>
>

165
new-web/pages/index.vue

@ -15,12 +15,8 @@
<img :src="require('~/static/' + config.logo)" />
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title class="white--text">{{
config.title
}}</v-list-item-title>
<v-list-item-subtitle class="white--text">{{
config.description
}}</v-list-item-subtitle>
<v-list-item-title class="white--text">{{ config.title }}</v-list-item-title>
<v-list-item-subtitle class="white--text">{{ config.description }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
@ -49,12 +45,8 @@
<img :src="require('~/static/' + config.network.icon)" />
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>{{
config.network.title
}}</v-list-item-title>
<v-list-item-subtitle>{{
config.network.algo
}}</v-list-item-subtitle>
<v-list-item-title>{{ config.network.title }}</v-list-item-title>
<v-list-item-subtitle>{{ config.network.algo }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
@ -68,12 +60,6 @@
}}
</li>
<li>{{ $tc('pages.home.mode', 0, { mode: config.mode }) }}</li>
<li>
{{ $t('pages.home.poweredBy') }}
<a href="https://github.com/yuriy0803/open-etc-pool-friends" target="_blank"
>open-etc-pool-friends</a
>.
</li>
<li>{{ $t('pages.home.protocols') }}</li>
</ul>
</v-card-text>
@ -103,25 +89,37 @@
:items-per-page="-1"
:no-data-text="$t('pages.home.noMiners')"
>
<template #[`item.account`]="{ item }">
<nuxt-link :to="'/account/' + item.account">{{
formatAccountHash(item.account)
}}</nuxt-link>
<template #item.account="{ item }">
<nuxt-link :to="'/account/' + item.account">{{ formatAccountHash(item.account) }}</nuxt-link>
</template>
<template #[`item.hashrate`]="{ item }">
{{ formatHashrate(item.hashrate, true) }}
</template>
<template #[`item.lastBeat`]="{ item }">
<template #item.lastBeat="{ item }">
{{ formatLastBeat(item.lastBeat) }}
</template>
</v-data-table>
</v-card>
</v-col>
<v-col cols="12" class="pa-0">
<v-row no-gutters align="center" justify="space-between">
<v-col cols="6">
<div class="chart-title">Pool Hashrate</div>
<div ref="poolChart"></div>
</v-col>
<v-col cols="6">
<div class="chart-title">Network Difficulty</div>
<div ref="netChart"></div>
</v-col>
</v-row>
</v-col>
</v-row>
</template>
<script>
import { formatDistance } from 'date-fns'
import ApexCharts from 'apexcharts'
import axios from 'axios'
export default {
data() {
@ -132,17 +130,9 @@ export default {
computed: {
headers() {
return [
{
text: this.$t('pages.home.account'),
align: 'start',
value: 'account',
},
{ text: this.$t('pages.home.account'), align: 'start', value: 'account' },
{ text: this.$t('pages.home.hashrate'), value: 'hashrate' },
{
text: this.$t('pages.home.lastBeat'),
align: 'right',
value: 'lastBeat',
},
{ text: this.$t('pages.home.lastBeat'), align: 'right', value: 'lastBeat' },
]
},
miners() {
@ -168,6 +158,9 @@ export default {
return this.$store.state.now
},
},
mounted() {
this.fetchPoolChartData()
},
methods: {
formatHashrate(bytes, showHash) {
const sizes = ['', 'K', 'M', 'G', 'T']
@ -195,6 +188,110 @@ export default {
includeSeconds: true,
})
},
},
fetchPoolChartData() {
axios
.get(this.config.api + '/stats')
.then(response => {
const netChartData = response.data.netCharts.map(data => ({
x: new Date(data.x * 1000).toLocaleString(navigator.language, {
hour12: false,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
day: '2-digit',
month: '2-digit',
year: '2-digit',
hour: '2-digit',
minute: '2-digit'
}),
y: data.y
}));
const poolChartData = response.data.poolCharts.map(data => ({
x: new Date(data.x * 1000).toLocaleString(navigator.language, {
hour12: false,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
day: '2-digit',
month: '2-digit',
year: '2-digit',
hour: '2-digit',
minute: '2-digit'
}),
y: data.y
}));
this.renderChart(netChartData, 'Network Difficulty', '#FF0000', this.$refs.netChart);
this.renderChart(poolChartData, 'Pool Hashrate', '#00FF00', this.$refs.poolChart);
})
.catch(error => {
console.error('Error fetching pool data:', error);
});
},
renderChart(chartData, name, color, element) {
const options = {
chart: {
type: 'area',
height: 350,
toolbar: {
show: false
},
zoom: false
},
series: [{
name: name,
data: chartData.map(data => ({
x: data.x,
y: data.y
}))
}],
colors: [color],
xaxis: {
categories: chartData.map(data => data.x),
labels: {
style: {
colors: ['#00FF00']
}
}
},
yaxis: {
labels: {
style: {
colors: ['#000000']
},
formatter: function (value) {
const sizes = ['H/s', 'KH/s', 'MH/s', 'GH/s', 'TH/s', 'PH/s']
if (value === 0) {
return 'n/a'
}
const i = Math.floor(Math.log(value) / Math.log(1000))
if (i === 0) {
return value + ' ' + sizes[i]
}
return (value / 1000 ** i).toFixed(3) + ' ' + sizes[i]
}
}
},
plotOptions: {
area: {
fillColor: '#FFFF00',
lineColor: '#00FFFF',
}
},
tooltip: {
enabled: true,
style: {
colors: ['#FFFFFF']
},
theme: 'dark'
},
dataLabels: {
enabled: false
}
};
const chart = new ApexCharts(element, options);
chart.render();
}
}
}
</script>
<style>
/* Your custom styles here */
</style>

2
new-web/params/networks.json

@ -28,7 +28,7 @@
"title": "Ubiq Mainnet",
"symbol": "UBQ",
"icon": "ubq.svg",
"blockTime": 88,
"blockTime": 15,
"epochLength": 30000,
"algo": "ubqhash"
}

6
new-web/plugins/apexcharts.js

@ -0,0 +1,6 @@
import VueApexCharts from 'vue-apexcharts'
import Vue from 'vue'
Vue.use(VueApexCharts)
Vue.component('apexchart', VueApexCharts)

5
new-web/plugins/clipboard.js

@ -0,0 +1,5 @@
import Vue from 'vue'
import VueClipboard from 'vue-clipboard2'
VueClipboard.config.autoSetContainer = true // modal fix
Vue.use(VueClipboard)

5
new-web/plugins/highlight.js

@ -0,0 +1,5 @@
import Vue from 'vue'
import VueHighlightJS from 'vue-highlightjs'
Vue.config.productionTip = false
Vue.use(VueHighlightJS)

4
new-web/plugins/notifications.js

@ -0,0 +1,4 @@
import Vue from 'vue'
import Notifications from 'vue-notification'
Vue.use(Notifications)

4
new-web/plugins/qrcode.js

@ -0,0 +1,4 @@
import Vue from 'vue'
import VueQrcode from '@chenfengyuan/vue-qrcode'
Vue.component(VueQrcode.name, VueQrcode)

4
new-web/plugins/smoothreflow.js

@ -0,0 +1,4 @@
import Vue from 'vue'
import smoothReflow from '~/components/util/SmoothReflow'
Vue.component('smoothReflow', smoothReflow)

29
new-web/scss/_custom.scss

@ -5,7 +5,7 @@ a {
}
.v-application {
font-family: Ubuntu Mono, monospace !important;
font-family: 'Ubuntu Mono', monospace !important;
font-style: normal;
font-variant: normal;
}
@ -15,24 +15,24 @@ a {
}
.h-100 {
height: calc(100vh - 80px)
height: calc(100vh - 80px);
}
.bg-transparent {
background-color: $transparent !important;
background-color: transparent !important;
}
.bb-1 {
border-bottom: 1px solid $grey3 !important;
border-bottom: 1px solid var(--grey3) !important;
}
.nuxt-content-highlight pre {
background-color: $transparent !important;
background-color: transparent !important;
border: none;
}
.nuxt-content-highlight pre code {
background-color:$transparent !important;
background-color: transparent !important;
text-shadow: none !important;
}
@ -40,23 +40,28 @@ a {
background-color: #1E1E1E !important;
}
// scrollbars
/* Scrollbars */
::-webkit-scrollbar {
width: 6px; /* for vertical scrollbars */
height: 6px; /* for horizontal scrollbars */
width: 6px; /* For vertical scrollbars */
height: 6px; /* For horizontal scrollbars */
}
::-webkit-scrollbar-track {
background: var(--v-borders-base) !important;
z-index: 4 !important
z-index: 4 !important;
}
::-webkit-scrollbar-thumb {
background: var(--v-primary-base) !important;
}
// firefox scrollbar z-index fix
/* Firefox scrollbar z-index fix */
.ff-scrollbar-fix {
transform: translate3d(0, 0, 0);
scrollbar-color: var(--v-primary-base) var(--v-borders-base);
scrollbar-width: thin;
}
.chart-title {
text-align: center;
font-weight: bold;
margin-bottom: 10px;
}

72
new-web/yarn.lock

@ -2698,6 +2698,18 @@ anymatch@^3.0.3, anymatch@~3.1.1:
normalize-path "^3.0.0"
picomatch "^2.0.4"
apexcharts@^3.41.0:
version "3.41.0"
resolved "https://registry.npmjs.org/apexcharts/-/apexcharts-3.41.0.tgz#7aef77275c19dfb925552d6fc8e027443a6d1337"
integrity sha512-FJXA7NVjxs1q+ptR3b1I+pN8K/gWuXn+qLZjFz8EHvJOokdgcuwa/HSe5aC465HW/LWnrjWLSTsOQejQbQ42hQ==
dependencies:
svg.draggable.js "^2.2.2"
svg.easing.js "^2.0.0"
svg.filter.js "^2.0.2"
svg.pathmorphing.js "^0.1.3"
svg.resize.js "^1.4.3"
svg.select.js "^3.0.1"
aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@ -11179,6 +11191,61 @@ svg-tags@^1.0.0:
resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764"
integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=
svg.draggable.js@^2.2.2:
version "2.2.2"
resolved "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz#c514a2f1405efb6f0263e7958f5b68fce50603ba"
integrity sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==
dependencies:
svg.js "^2.0.1"
svg.easing.js@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz#8aa9946b0a8e27857a5c40a10eba4091e5691f12"
integrity sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==
dependencies:
svg.js ">=2.3.x"
svg.filter.js@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz#91008e151389dd9230779fcbe6e2c9a362d1c203"
integrity sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==
dependencies:
svg.js "^2.2.5"
svg.js@>=2.3.x, svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5:
version "2.7.1"
resolved "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz#eb977ed4737001eab859949b4a398ee1bb79948d"
integrity sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==
svg.pathmorphing.js@^0.1.3:
version "0.1.3"
resolved "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz#c25718a1cc7c36e852ecabc380e758ac09bb2b65"
integrity sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==
dependencies:
svg.js "^2.4.0"
svg.resize.js@^1.4.3:
version "1.4.3"
resolved "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz#885abd248e0cd205b36b973c4b578b9a36f23332"
integrity sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==
dependencies:
svg.js "^2.6.5"
svg.select.js "^2.1.2"
svg.select.js@^2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz#e41ce13b1acff43a7441f9f8be87a2319c87be73"
integrity sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==
dependencies:
svg.js "^2.2.5"
svg.select.js@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz#a4198e359f3825739226415f82176a90ea5cc917"
integrity sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==
dependencies:
svg.js "^2.6.5"
svgo@^1.0.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167"
@ -11941,6 +12008,11 @@ vm-browserify@^1.0.1:
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
vue-apexcharts@^1.6.2:
version "1.6.2"
resolved "https://registry.npmjs.org/vue-apexcharts/-/vue-apexcharts-1.6.2.tgz#0547826067f97e8ea67ca9423e524eb6669746ad"
integrity sha512-9HS3scJwWgKjmkcWIf+ndNDR0WytUJD8Ju0V2ZYcjYtlTLwJAf2SKUlBZaQTkDmwje/zMgulvZRi+MXmi+WkKw==
vue-client-only@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/vue-client-only/-/vue-client-only-2.0.0.tgz#ddad8d675ee02c761a14229f0e440e219de1da1c"

Loading…
Cancel
Save