chore: code formatting
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import app from "./instance.mjs"
|
||||
;(async function() {
|
||||
await app({sandbox:process.env.SANDBOX})
|
||||
await app({sandbox: process.env.SANDBOX})
|
||||
})()
|
||||
|
||||
@@ -18,7 +18,7 @@ export default async function({sandbox = false} = {}) {
|
||||
//Sandbox mode
|
||||
if (sandbox) {
|
||||
console.debug("metrics/app > sandbox mode is specified, enabling advanced features")
|
||||
Object.assign(conf.settings, {sandbox:true, optimize:true, cached:0, "plugins.default":true, extras:{default:true}})
|
||||
Object.assign(conf.settings, {sandbox: true, optimize: true, cached: 0, "plugins.default": true, extras: {default: true}})
|
||||
}
|
||||
const {token, maxusers = 0, restricted = [], debug = false, cached = 30 * 60 * 1000, port = 3000, ratelimiter = null, plugins = null} = conf.settings
|
||||
const mock = sandbox || conf.settings.mocked
|
||||
@@ -48,10 +48,10 @@ export default async function({sandbox = false} = {}) {
|
||||
conf.settings.token = "MOCKED_TOKEN"
|
||||
}
|
||||
if (debug)
|
||||
console.debug(util.inspect(conf.settings, {depth:Infinity, maxStringLength:256}))
|
||||
console.debug(util.inspect(conf.settings, {depth: Infinity, maxStringLength: 256}))
|
||||
|
||||
//Load octokits
|
||||
const api = {graphql:octokit.graphql.defaults({headers:{authorization:`token ${token}`}}), rest:new OctokitRest.Octokit({auth:token})}
|
||||
const api = {graphql: octokit.graphql.defaults({headers: {authorization: `token ${token}`}}), rest: new OctokitRest.Octokit({auth: token})}
|
||||
//Apply mocking if needed
|
||||
if (mock)
|
||||
Object.assign(api, await mocks(api))
|
||||
@@ -68,8 +68,8 @@ export default async function({sandbox = false} = {}) {
|
||||
skip(req, _res) {
|
||||
return !!cache.get(req.params.login)
|
||||
},
|
||||
message:"Too many requests: retry later",
|
||||
headers:true,
|
||||
message: "Too many requests: retry later",
|
||||
headers: true,
|
||||
...ratelimiter,
|
||||
}))
|
||||
}
|
||||
@@ -84,24 +84,24 @@ export default async function({sandbox = false} = {}) {
|
||||
})
|
||||
|
||||
//Base routes
|
||||
const limiter = ratelimit({max:debug ? Number.MAX_SAFE_INTEGER : 60, windowMs:60 * 1000, headers:false})
|
||||
const limiter = ratelimit({max: debug ? Number.MAX_SAFE_INTEGER : 60, windowMs: 60 * 1000, headers: false})
|
||||
const metadata = Object.fromEntries(
|
||||
Object.entries(conf.metadata.plugins)
|
||||
.map(([key, value]) => [key, Object.fromEntries(Object.entries(value).filter(([key]) => ["name", "icon", "category", "web", "supports", "scopes"].includes(key)))])
|
||||
.map(([key, value]) => [key, key === "core" ? {...value, web:Object.fromEntries(Object.entries(value.web).filter(([key]) => /^config[.]/.test(key)).map(([key, value]) => [key.replace(/^config[.]/, ""), value]))} : value]),
|
||||
.map(([key, value]) => [key, key === "core" ? {...value, web: Object.fromEntries(Object.entries(value.web).filter(([key]) => /^config[.]/.test(key)).map(([key, value]) => [key.replace(/^config[.]/, ""), value]))} : value]),
|
||||
)
|
||||
const enabled = Object.entries(metadata).filter(([_name, {category}]) => category !== "core").map(([name]) => ({name, category:metadata[name]?.category ?? "community", enabled:plugins[name]?.enabled ?? false}))
|
||||
const templates = Object.entries(Templates).map(([name]) => ({name, enabled:(conf.settings.templates.enabled.length ? conf.settings.templates.enabled.includes(name) : true) ?? false}))
|
||||
const actions = {flush:new Map()}
|
||||
const requests = {rest:{limit:0, used:0, remaining:0, reset:NaN}, graphql:{limit:0, used:0, remaining:0, reset:NaN}}
|
||||
const enabled = Object.entries(metadata).filter(([_name, {category}]) => category !== "core").map(([name]) => ({name, category: metadata[name]?.category ?? "community", enabled: plugins[name]?.enabled ?? false}))
|
||||
const templates = Object.entries(Templates).map(([name]) => ({name, enabled: (conf.settings.templates.enabled.length ? conf.settings.templates.enabled.includes(name) : true) ?? false}))
|
||||
const actions = {flush: new Map()}
|
||||
const requests = {rest: {limit: 0, used: 0, remaining: 0, reset: NaN}, graphql: {limit: 0, used: 0, remaining: 0, reset: NaN}}
|
||||
let _requests_refresh = false
|
||||
if (!conf.settings.notoken) {
|
||||
const refresh = async () => {
|
||||
try {
|
||||
const {limit} = await graphql("{ limit:rateLimit {limit remaining reset:resetAt used} }")
|
||||
Object.assign(requests, {
|
||||
rest:(await rest.rateLimit.get()).data.rate,
|
||||
graphql:{...limit, reset:new Date(limit.reset).getTime()},
|
||||
rest: (await rest.rateLimit.get()).data.rate,
|
||||
graphql: {...limit, reset: new Date(limit.reset).getTime()},
|
||||
})
|
||||
}
|
||||
catch {
|
||||
@@ -245,9 +245,9 @@ export default async function({sandbox = false} = {}) {
|
||||
console.debug(`metrics/app/${login} > awaiting pending request`)
|
||||
await pending.get(login)
|
||||
}
|
||||
else
|
||||
else {
|
||||
pending.set(login, new Promise(_solve => solve = _solve))
|
||||
|
||||
}
|
||||
|
||||
//Read cached data if possible
|
||||
if ((!debug) && (cached) && (cache.get(login))) {
|
||||
@@ -273,7 +273,7 @@ export default async function({sandbox = false} = {}) {
|
||||
try {
|
||||
//Render
|
||||
const q = req.query
|
||||
console.debug(`metrics/app/${login} > ${util.inspect(q, {depth:Infinity, maxStringLength:256})}`)
|
||||
console.debug(`metrics/app/${login} > ${util.inspect(q, {depth: Infinity, maxStringLength: 256})}`)
|
||||
if ((q["config.presets"]) && (conf.settings.extras?.presets ?? conf.settings.extras?.default ?? false)) {
|
||||
console.debug(`metrics/app/${login} > presets have been specified, loading them`)
|
||||
Object.assign(q, await presets(q["config.presets"]))
|
||||
@@ -283,9 +283,9 @@ export default async function({sandbox = false} = {}) {
|
||||
rest,
|
||||
plugins,
|
||||
conf,
|
||||
die:q["plugins.errors.fatal"] ?? false,
|
||||
verify:q.verify ?? false,
|
||||
convert:["svg", "jpeg", "png", "json", "markdown", "markdown-pdf", "insights"].includes(q["config.output"]) ? q["config.output"] : null,
|
||||
die: q["plugins.errors.fatal"] ?? false,
|
||||
verify: q.verify ?? false,
|
||||
convert: ["svg", "jpeg", "png", "json", "markdown", "markdown-pdf", "insights"].includes(q["config.output"]) ? q["config.output"] : null,
|
||||
}, {Plugins, Templates})
|
||||
//Cache
|
||||
if ((!debug) && (cached)) {
|
||||
@@ -331,13 +331,14 @@ export default async function({sandbox = false} = {}) {
|
||||
})
|
||||
|
||||
//Listen
|
||||
app.listen(port, () => console.log([
|
||||
app.listen(port, () =>
|
||||
console.log([
|
||||
`Listening on port │ ${port}`,
|
||||
`Debug mode │ ${debug}`,
|
||||
`Mocked data │ ${conf.settings.mocked ?? false}`,
|
||||
`Restricted to users │ ${restricted.size ? [...restricted].join(", ") : "(unrestricted)"}`,
|
||||
`Cached time │ ${cached} seconds`,
|
||||
`Rate limiter │ ${ratelimiter ? util.inspect(ratelimiter, {depth:Infinity, maxStringLength:256}) : "(enabled)"}`,
|
||||
`Rate limiter │ ${ratelimiter ? util.inspect(ratelimiter, {depth: Infinity, maxStringLength: 256}) : "(enabled)"}`,
|
||||
`Max simultaneous users │ ${maxusers ? `${maxusers} users` : "(unrestricted)"}`,
|
||||
`Plugins enabled │ ${enabled.map(({name}) => name).join(", ")}`,
|
||||
`SVG optimization │ ${conf.settings.optimize ?? false}`,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
async mounted() {
|
||||
//Palette
|
||||
try {
|
||||
this.palette = (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light")
|
||||
this.palette = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
|
||||
}
|
||||
catch (error) {}
|
||||
//Embed
|
||||
@@ -26,17 +26,17 @@
|
||||
await Promise.all([
|
||||
//GitHub limit tracker
|
||||
(async () => {
|
||||
const { data: requests } = await axios.get("/.requests")
|
||||
const {data: requests} = await axios.get("/.requests")
|
||||
this.requests = requests
|
||||
})(),
|
||||
//Version
|
||||
(async () => {
|
||||
const { data: version } = await axios.get("/.version")
|
||||
const {data: version} = await axios.get("/.version")
|
||||
this.version = `v${version}`
|
||||
})(),
|
||||
//Hosted
|
||||
(async () => {
|
||||
const { data: hosted } = await axios.get("/.hosted")
|
||||
const {data: hosted} = await axios.get("/.hosted")
|
||||
this.hosted = hosted
|
||||
})(),
|
||||
])
|
||||
@@ -89,12 +89,12 @@
|
||||
this.metrics = (await axios.get(`/about/query/${this.user}`)).data
|
||||
}
|
||||
catch (error) {
|
||||
this.error = { code: error.response.status, message: error.response.data }
|
||||
this.error = {code: error.response.status, message: error.response.data}
|
||||
}
|
||||
finally {
|
||||
this.pending = false
|
||||
try {
|
||||
const { data: requests } = await axios.get("/.requests")
|
||||
const {data: requests} = await axios.get("/.requests")
|
||||
this.requests = requests
|
||||
}
|
||||
catch {}
|
||||
@@ -104,10 +104,10 @@
|
||||
//Computed properties
|
||||
computed: {
|
||||
ranked() {
|
||||
return this.metrics?.rendered.plugins.achievements.list?.filter(({ leaderboard }) => leaderboard).sort((a, b) => a.leaderboard.type.localeCompare(b.leaderboard.type)) ?? []
|
||||
return this.metrics?.rendered.plugins.achievements.list?.filter(({leaderboard}) => leaderboard).sort((a, b) => a.leaderboard.type.localeCompare(b.leaderboard.type)) ?? []
|
||||
},
|
||||
achievements() {
|
||||
return this.metrics?.rendered.plugins.achievements.list?.filter(({ leaderboard }) => !leaderboard).filter(({ title }) => !/(?:automator|octonaut|infographile)/i.test(title)) ?? []
|
||||
return this.metrics?.rendered.plugins.achievements.list?.filter(({leaderboard}) => !leaderboard).filter(({title}) => !/(?:automator|octonaut|infographile)/i.test(title)) ?? []
|
||||
},
|
||||
introduction() {
|
||||
return this.metrics?.rendered.plugins.introduction?.text ?? ""
|
||||
@@ -138,8 +138,8 @@
|
||||
account() {
|
||||
if (!this.metrics)
|
||||
return null
|
||||
const { login, name } = this.metrics.rendered.user
|
||||
return { login, name, avatar: this.metrics.rendered.computed.avatar, type: this.metrics?.rendered.account }
|
||||
const {login, name} = this.metrics.rendered.user
|
||||
return {login, name, avatar: this.metrics.rendered.computed.avatar, type: this.metrics?.rendered.account}
|
||||
},
|
||||
url() {
|
||||
return `${window.location.protocol}//${window.location.host}/about/${this.user}`
|
||||
@@ -160,7 +160,7 @@
|
||||
embed: false,
|
||||
localstorage: false,
|
||||
searchable: false,
|
||||
requests: { rest: { limit: 0, used: 0, remaining: 0, reset: NaN }, graphql: { limit: 0, used: 0, remaining: 0, reset: NaN } },
|
||||
requests: {rest: {limit: 0, used: 0, remaining: 0, reset: NaN}, graphql: {limit: 0, used: 0, remaining: 0, reset: NaN}},
|
||||
palette: "light",
|
||||
metrics: null,
|
||||
pending: false,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;(async function() {
|
||||
//Init
|
||||
const { data: metadata } = await axios.get("/.plugins.metadata")
|
||||
const {data: metadata} = await axios.get("/.plugins.metadata")
|
||||
delete metadata.core.web.output
|
||||
delete metadata.core.web.twemojis
|
||||
//App
|
||||
@@ -11,49 +11,49 @@
|
||||
//Interpolate config from browser
|
||||
try {
|
||||
this.config.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone
|
||||
this.palette = (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light")
|
||||
this.palette = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
|
||||
}
|
||||
catch (error) {}
|
||||
//Init
|
||||
await Promise.all([
|
||||
//GitHub limit tracker
|
||||
(async () => {
|
||||
const { data: requests } = await axios.get("/.requests")
|
||||
const {data: requests} = await axios.get("/.requests")
|
||||
this.requests = requests
|
||||
})(),
|
||||
//Templates
|
||||
(async () => {
|
||||
const { data: templates } = await axios.get("/.templates")
|
||||
const {data: templates} = await axios.get("/.templates")
|
||||
templates.sort((a, b) => (a.name.startsWith("@") ^ b.name.startsWith("@")) ? (a.name.startsWith("@") ? 1 : -1) : a.name.localeCompare(b.name))
|
||||
this.templates.list = templates
|
||||
this.templates.selected = templates[0]?.name || "classic"
|
||||
})(),
|
||||
//Plugins
|
||||
(async () => {
|
||||
const { data: plugins } = await axios.get("/.plugins")
|
||||
this.plugins.list = plugins.filter(({ name }) => metadata[name]?.supports.includes("user") || metadata[name]?.supports.includes("organization"))
|
||||
const categories = [...new Set(this.plugins.list.map(({ category }) => category))]
|
||||
const {data: plugins} = await axios.get("/.plugins")
|
||||
this.plugins.list = plugins.filter(({name}) => metadata[name]?.supports.includes("user") || metadata[name]?.supports.includes("organization"))
|
||||
const categories = [...new Set(this.plugins.list.map(({category}) => category))]
|
||||
this.plugins.categories = Object.fromEntries(categories.map(category => [category, this.plugins.list.filter(value => category === value.category)]))
|
||||
})(),
|
||||
//Base
|
||||
(async () => {
|
||||
const { data: base } = await axios.get("/.plugins.base")
|
||||
const {data: base} = await axios.get("/.plugins.base")
|
||||
this.plugins.base = base
|
||||
this.plugins.enabled.base = Object.fromEntries(base.map(key => [key, true]))
|
||||
})(),
|
||||
//Version
|
||||
(async () => {
|
||||
const { data: version } = await axios.get("/.version")
|
||||
const {data: version} = await axios.get("/.version")
|
||||
this.version = `v${version}`
|
||||
})(),
|
||||
//Hosted
|
||||
(async () => {
|
||||
const { data: hosted } = await axios.get("/.hosted")
|
||||
const {data: hosted} = await axios.get("/.hosted")
|
||||
this.hosted = hosted
|
||||
})(),
|
||||
])
|
||||
//Generate placeholder
|
||||
this.mock({ timeout: 200 })
|
||||
this.mock({timeout: 200})
|
||||
setInterval(() => {
|
||||
const marker = document.querySelector("#metrics-end")
|
||||
if (marker) {
|
||||
@@ -62,7 +62,7 @@
|
||||
}
|
||||
}, 100)
|
||||
},
|
||||
components: { Prism: PrismComponent },
|
||||
components: {Prism: PrismComponent},
|
||||
//Watchers
|
||||
watch: {
|
||||
tab: {
|
||||
@@ -90,10 +90,10 @@
|
||||
tab: "overview",
|
||||
palette: "light",
|
||||
clipboard: null,
|
||||
requests: { rest: { limit: 0, used: 0, remaining: 0, reset: NaN }, graphql: { limit: 0, used: 0, remaining: 0, reset: NaN } },
|
||||
requests: {rest: {limit: 0, used: 0, remaining: 0, reset: NaN}, graphql: {limit: 0, used: 0, remaining: 0, reset: NaN}},
|
||||
cached: new Map(),
|
||||
config: Object.fromEntries(Object.entries(metadata.core.web).map(([key, { defaulted }]) => [key, defaulted])),
|
||||
metadata: Object.fromEntries(Object.entries(metadata).map(([key, { web }]) => [key, web])),
|
||||
config: Object.fromEntries(Object.entries(metadata.core.web).map(([key, {defaulted}]) => [key, defaulted])),
|
||||
metadata: Object.fromEntries(Object.entries(metadata).map(([key, {web}]) => [key, web])),
|
||||
hosted: null,
|
||||
docs: {
|
||||
overview: {
|
||||
@@ -121,15 +121,15 @@
|
||||
"base.community": "Community stats",
|
||||
"base.repositories": "Repositories metrics",
|
||||
"base.metadata": "Metadata",
|
||||
...Object.fromEntries(Object.entries(metadata).map(([key, { name }]) => [key, name])),
|
||||
...Object.fromEntries(Object.entries(metadata).map(([key, {name}]) => [key, name])),
|
||||
},
|
||||
options: {
|
||||
descriptions: { ...(Object.assign({}, ...Object.entries(metadata).flatMap(([key, { web }]) => web))) },
|
||||
descriptions: {...(Object.assign({}, ...Object.entries(metadata).flatMap(([key, {web}]) => web)))},
|
||||
...(Object.fromEntries(
|
||||
Object.entries(
|
||||
Object.assign({}, ...Object.entries(metadata).flatMap(([key, { web }]) => web)),
|
||||
Object.assign({}, ...Object.entries(metadata).flatMap(([key, {web}]) => web)),
|
||||
)
|
||||
.map(([key, { defaulted }]) => [key, defaulted]),
|
||||
.map(([key, {defaulted}]) => [key, defaulted]),
|
||||
)),
|
||||
},
|
||||
},
|
||||
@@ -157,7 +157,7 @@
|
||||
computed: {
|
||||
//Unusable plugins
|
||||
unusable() {
|
||||
return this.plugins.list.filter(({ name }) => this.plugins.enabled[name]).filter(({ enabled }) => !enabled).map(({ name }) => name)
|
||||
return this.plugins.list.filter(({name}) => this.plugins.enabled[name]).filter(({enabled}) => !enabled).map(({name}) => name)
|
||||
},
|
||||
//User's avatar
|
||||
avatar() {
|
||||
@@ -239,13 +239,13 @@
|
||||
` base: ${Object.entries(this.plugins.enabled.base).filter(([key, value]) => value).map(([key]) => key).join(", ") || '""'}`,
|
||||
...[
|
||||
...Object.entries(this.plugins.options).filter(([key, value]) => (key in metadata.base.web) && (value !== metadata.base.web[key]?.defaulted)).map(([key, value]) =>
|
||||
` ${key.replace(/[.]/g, "_")}: ${typeof value === "boolean" ? { true: "yes", false: "no" }[value] : value}`
|
||||
` ${key.replace(/[.]/g, "_")}: ${typeof value === "boolean" ? {true: "yes", false: "no"}[value] : value}`
|
||||
),
|
||||
...Object.entries(this.plugins.enabled).filter(([key, value]) => (key !== "base") && (value)).map(([key]) => ` plugin_${key}: yes`),
|
||||
...Object.entries(this.plugins.options).filter(([key, value]) => value).filter(([key, value]) => this.plugins.enabled[key.split(".")[0]]).map(([key, value]) =>
|
||||
` plugin_${key.replace(/[.]/g, "_")}: ${typeof value === "boolean" ? { true: "yes", false: "no" }[value] : value}`
|
||||
` plugin_${key.replace(/[.]/g, "_")}: ${typeof value === "boolean" ? {true: "yes", false: "no"}[value] : value}`
|
||||
),
|
||||
...Object.entries(this.config).filter(([key, value]) => (value) && (value !== metadata.core.web[key]?.defaulted)).map(([key, value]) => ` config_${key.replace(/[.]/g, "_")}: ${typeof value === "boolean" ? { true: "yes", false: "no" }[value] : value}`),
|
||||
...Object.entries(this.config).filter(([key, value]) => (value) && (value !== metadata.core.web[key]?.defaulted)).map(([key, value]) => ` config_${key.replace(/[.]/g, "_")}: ${typeof value === "boolean" ? {true: "yes", false: "no"}[value] : value}`),
|
||||
].sort(),
|
||||
].join("\n")
|
||||
},
|
||||
@@ -276,7 +276,7 @@
|
||||
methods: {
|
||||
//Refresh computed properties
|
||||
async refresh() {
|
||||
const keys = { action: ["scopes", "action"], markdown: ["url", "embed"] }[this.tab]
|
||||
const keys = {action: ["scopes", "action"], markdown: ["url", "embed"]}[this.tab]
|
||||
if (keys) {
|
||||
for (const key of keys)
|
||||
this._computedWatchers[key]?.run()
|
||||
@@ -284,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
//Load and render placeholder image
|
||||
async mock({ timeout = 600 } = {}) {
|
||||
async mock({timeout = 600} = {}) {
|
||||
this.refresh()
|
||||
clearTimeout(this.templates.placeholder.timeout)
|
||||
this.templates.placeholder.timeout = setTimeout(async () => {
|
||||
@@ -315,12 +315,12 @@
|
||||
this.generated.error = null
|
||||
}
|
||||
catch (error) {
|
||||
this.generated.error = { code: error.response.status, message: error.response.data }
|
||||
this.generated.error = {code: error.response.status, message: error.response.data}
|
||||
}
|
||||
finally {
|
||||
this.generated.pending = false
|
||||
try {
|
||||
const { data: requests } = await axios.get("/.requests")
|
||||
const {data: requests} = await axios.get("/.requests")
|
||||
this.requests = requests
|
||||
}
|
||||
catch {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;(function({ axios, faker, ejs } = { axios: globalThis.axios, faker: globalThis.faker, ejs: globalThis.ejs }) {
|
||||
;(function({axios, faker, ejs} = {axios: globalThis.axios, faker: globalThis.faker, ejs: globalThis.ejs}) {
|
||||
//Load assets
|
||||
const cached = new Map()
|
||||
async function load(url) {
|
||||
@@ -31,7 +31,7 @@
|
||||
//Placeholder function
|
||||
globalThis.placeholder = async function(set) {
|
||||
//Load templates informations
|
||||
let { image, style, fonts, partials } = await load(`/.templates/${set.templates.selected}`)
|
||||
let {image, style, fonts, partials} = await load(`/.templates/${set.templates.selected}`)
|
||||
await Promise.all(partials.map(async partial => await load(`/.templates/${set.templates.selected}/partials/${escape(partial)}.ejs`)))
|
||||
//Trap includes
|
||||
image = image.replace(/<%-\s*await include[(](`.*?[.]ejs`)[)]\s*%>/g, (m, g) => `<%- await $include(${g}) %>`)
|
||||
@@ -45,11 +45,11 @@
|
||||
partials: new Set([...(set.config.order || "").split(",").map(x => x.trim()).filter(x => partials.includes(x)), ...partials]),
|
||||
//Plural helper
|
||||
s(value, end = "") {
|
||||
return value !== 1 ? { y: "ies", "": "s" }[end] : end
|
||||
return value !== 1 ? {y: "ies", "": "s"}[end] : end
|
||||
},
|
||||
//Formatter helper
|
||||
f(n, { sign = false } = {}) {
|
||||
for (const { u, v } of [{ u: "b", v: 10 ** 9 }, { u: "m", v: 10 ** 6 }, { u: "k", v: 10 ** 3 }]) {
|
||||
f(n, {sign = false} = {}) {
|
||||
for (const {u, v} of [{u: "b", v: 10 ** 9}, {u: "m", v: 10 ** 6}, {u: "k", v: 10 ** 3}]) {
|
||||
if (n / v >= 1)
|
||||
return `${(sign) && (n > 0) ? "+" : ""}${(n / v).toFixed(2).substr(0, 4).replace(/[.]0*$/, "")}${u}`
|
||||
}
|
||||
@@ -58,10 +58,10 @@
|
||||
//Trap for includes
|
||||
async $include(path) {
|
||||
const partial = await load(`/.templates/${set.templates.selected}/${escape(path)}`)
|
||||
return await ejs.render(partial, data, { async: true, rmWhitespace: true })
|
||||
return await ejs.render(partial, data, {async: true, rmWhitespace: true})
|
||||
},
|
||||
//Meta-data
|
||||
meta: { version: set.version, author: "lowlighter", generated: new Date().toGMTString().replace(/GMT$/g, "").trim() },
|
||||
meta: {version: set.version, author: "lowlighter", generated: new Date().toGMTString().replace(/GMT$/g, "").trim()},
|
||||
//Animated
|
||||
animated: false,
|
||||
//Display size
|
||||
@@ -70,30 +70,30 @@
|
||||
//Config
|
||||
config: set.config,
|
||||
//Extras
|
||||
extras: { css: options["extras.css"] ?? "" },
|
||||
extras: {css: options["extras.css"] ?? ""},
|
||||
//Base elements
|
||||
base: set.plugins.enabled.base,
|
||||
//Computed elements
|
||||
computed: {
|
||||
commits: faker.datatype.number(10000),
|
||||
sponsorships: faker.datatype.number(10),
|
||||
licenses: { favorite: [""], used: { MIT: 1 }, about: {} },
|
||||
token: { scopes: [] },
|
||||
licenses: {favorite: [""], used: {MIT: 1}, about: {}},
|
||||
token: {scopes: []},
|
||||
repositories: {
|
||||
watchers: faker.datatype.number(1000),
|
||||
stargazers: faker.datatype.number(10000),
|
||||
issues_open: faker.datatype.number(1000),
|
||||
issues_closed: faker.datatype.number(1000),
|
||||
pr_open: faker.datatype.number(1000),
|
||||
pr_closed: { totalCount: faker.datatype.number(100) },
|
||||
pr_closed: {totalCount: faker.datatype.number(100)},
|
||||
pr_merged: faker.datatype.number(1000),
|
||||
forks: faker.datatype.number(1000),
|
||||
releases: faker.datatype.number(1000),
|
||||
},
|
||||
diskUsage: `${faker.datatype.float({ min: 1, max: 999 }).toFixed(1)}MB`,
|
||||
registration: `${faker.datatype.number({ min: 2, max: 10 })} years ago`,
|
||||
diskUsage: `${faker.datatype.float({min: 1, max: 999}).toFixed(1)}MB`,
|
||||
registration: `${faker.datatype.number({min: 2, max: 10})} years ago`,
|
||||
cakeday: false,
|
||||
calendar: new Array(14).fill(null).map(_ => ({ color: faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"]) })),
|
||||
calendar: new Array(14).fill(null).map(_ => ({color: faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])})),
|
||||
avatar: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
|
||||
},
|
||||
//User data
|
||||
@@ -107,12 +107,12 @@
|
||||
websiteUrl: options["pagespeed.url"] || "(attached website)",
|
||||
isHireable: false,
|
||||
twitterUsername: options["tweets.user"] || "(attached Twitter account)",
|
||||
repositories: { totalCount: faker.datatype.number(100), totalDiskUsage: faker.datatype.number(100000), nodes: [] },
|
||||
packages: { totalCount: faker.datatype.number(10) },
|
||||
starredRepositories: { totalCount: faker.datatype.number(1000) },
|
||||
watching: { totalCount: faker.datatype.number(100) },
|
||||
sponsorshipsAsSponsor: { totalCount: faker.datatype.number(10) },
|
||||
sponsorshipsAsMaintainer: { totalCount: faker.datatype.number(10) },
|
||||
repositories: {totalCount: faker.datatype.number(100), totalDiskUsage: faker.datatype.number(100000), nodes: []},
|
||||
packages: {totalCount: faker.datatype.number(10)},
|
||||
starredRepositories: {totalCount: faker.datatype.number(1000)},
|
||||
watching: {totalCount: faker.datatype.number(100)},
|
||||
sponsorshipsAsSponsor: {totalCount: faker.datatype.number(10)},
|
||||
sponsorshipsAsMaintainer: {totalCount: faker.datatype.number(10)},
|
||||
contributionsCollection: {
|
||||
totalRepositoriesWithContributedCommits: faker.datatype.number(100),
|
||||
totalCommitContributions: faker.datatype.number(10000),
|
||||
@@ -121,12 +121,12 @@
|
||||
totalPullRequestContributions: faker.datatype.number(1000),
|
||||
totalPullRequestReviewContributions: faker.datatype.number(1000),
|
||||
},
|
||||
calendar: { contributionCalendar: { weeks: [] } },
|
||||
repositoriesContributedTo: { totalCount: faker.datatype.number(100) },
|
||||
followers: { totalCount: faker.datatype.number(1000) },
|
||||
following: { totalCount: faker.datatype.number(1000) },
|
||||
issueComments: { totalCount: faker.datatype.number(1000) },
|
||||
organizations: { totalCount: faker.datatype.number(10) },
|
||||
calendar: {contributionCalendar: {weeks: []}},
|
||||
repositoriesContributedTo: {totalCount: faker.datatype.number(100)},
|
||||
followers: {totalCount: faker.datatype.number(1000)},
|
||||
following: {totalCount: faker.datatype.number(1000)},
|
||||
issueComments: {totalCount: faker.datatype.number(1000)},
|
||||
organizations: {totalCount: faker.datatype.number(10)},
|
||||
},
|
||||
//Plugins
|
||||
plugins: {
|
||||
@@ -148,7 +148,7 @@
|
||||
id: faker.datatype.number(100000000000000).toString(),
|
||||
created_at: faker.date.recent(),
|
||||
entities: {
|
||||
mentions: [{ start: 22, end: 33, username: "lowlighter" }],
|
||||
mentions: [{start: 22, end: 33, username: "lowlighter"}],
|
||||
},
|
||||
text: 'Checkout metrics from <span class="mention">@lowlighter</span> ! <span class="hashtag">#GitHub</span> ',
|
||||
mentions: ["lowlighter"],
|
||||
@@ -177,7 +177,7 @@
|
||||
? ({
|
||||
traffic: {
|
||||
views: {
|
||||
count: `${faker.datatype.number({ min: 10, max: 100 })}.${faker.datatype.number(9)}k`,
|
||||
count: `${faker.datatype.number({min: 10, max: 100})}.${faker.datatype.number(9)}k`,
|
||||
uniques: `${faker.datatype.number(10)}.${faker.datatype.number(9)}k`,
|
||||
},
|
||||
},
|
||||
@@ -264,7 +264,7 @@
|
||||
? {
|
||||
user: {
|
||||
commits: faker.datatype.number(100),
|
||||
percentage: faker.datatype.float({ max: 1 }),
|
||||
percentage: faker.datatype.float({max: 1}),
|
||||
maintainer: false,
|
||||
stars: faker.datatype.number(100),
|
||||
},
|
||||
@@ -365,7 +365,7 @@
|
||||
unlock: null,
|
||||
text: faker.lorem.sentence(),
|
||||
get icon() {
|
||||
const colors = { S: ["#FF0000", "#FF8500"], A: ["#B59151", "#FFD576"], B: ["#7D6CFF", "#B2A8FF"], C: ["#2088FF", "#79B8FF"], $: ["#FF48BD", "#FF92D8"], X: ["#7A7A7A", "#B0B0B0"] }
|
||||
const colors = {S: ["#FF0000", "#FF8500"], A: ["#B59151", "#FFD576"], B: ["#7D6CFF", "#B2A8FF"], C: ["#2088FF", "#79B8FF"], $: ["#FF48BD", "#FF92D8"], X: ["#7A7A7A", "#B0B0B0"]}
|
||||
return `<g xmlns="http://www.w3.org/2000/svg" stroke-linecap="round" stroke-width="2" fill="none" fill-rule="evenodd"><g stroke-linejoin="round"><g stroke="#secondary"><path d="M8 43a3 3 0 100 6 3 3 0 000-6zm40 0a3.001 3.001 0 10.002 6.002A3.001 3.001 0 0048 43zm-18 3h-4.971m-11.045 0H11M45 46h-4"/></g><path stroke="#primary" d="M13 51h28M36.992 45.276l6.375-8.017c1.488.63 3.272.29 4.414-.977a3.883 3.883 0 00.658-4.193l-1.96 2.174-1.936-.151-.406-1.955 1.96-2.173a3.898 3.898 0 00-4.107 1.092 3.886 3.886 0 00-.512 4.485l-7.317 7.169c-1.32 1.314-.807 2.59-.236 3.105.67.601 1.888.845 3.067-.56z"/><g stroke="#primary"><path d="M12.652 31.063l9.442 12.578a.512.512 0 01-.087.716l-2.396 1.805a.512.512 0 01-.712-.114L9.46 33.47l-.176-3.557 3.37 1.15zM17.099 43.115l2.395-1.806"/></g></g><path d="M25.68 36.927v-2.54a2.227 2.227 0 01.37-1.265c-.526-.04-3.84-.371-3.84-4.302 0-1.013.305-1.839.915-2.477a4.989 4.989 0 01-.146-1.86c.087-.882.946-.823 2.577.178 1.277-.47 2.852-.47 4.725 0 .248-.303 2.434-1.704 2.658-.268.047.296.016.946-.093 1.95.516.524.776 1.358.78 2.501.007 2.261-1.26 3.687-3.8 4.278.24.436.355.857.346 1.264a117.57 117.57 0 000 2.614c2.43-.744 4.228-2.06 5.395-3.95.837-1.356 1.433-2.932 1.433-4.865 0-2.886-1.175-4.984-2.5-6.388C32.714 19.903 30.266 19 28 19a9.094 9.094 0 00-6.588 2.897C20.028 23.393 19 25.507 19 28.185c0 2.026.701 3.945 1.773 5.38 1.228 1.643 2.864 2.764 4.907 3.362zM52.98 25.002l-3.07 3.065-1.49-1.485M6.98 25.002l-3.07 3.065-1.49-1.485" stroke="#primary" stroke-linejoin="round"/><path d="M19.001 11V9a2 2 0 012-2h14a2 2 0 012 2v2m-21 12.028v-10.03a2 2 0 012-1.998h20a2 2 0 012 2v10.028" stroke="#secondary" stroke-linejoin="round"/><path stroke="#secondary" d="M28.001 7V3M15.039 7.797c-5.297 3.406-9.168 8.837-10.517 15.2m46.737-.936c-1.514-5.949-5.25-11.01-10.273-14.248"/></g>`
|
||||
.replace(/#primary/g, colors[this.rank][0])
|
||||
.replace(/#secondary/g, colors[this.rank][1])
|
||||
@@ -374,9 +374,9 @@
|
||||
progress: faker.datatype.number(100) / 100,
|
||||
value: faker.datatype.number(1000),
|
||||
}))
|
||||
.filter(({ rank }) => options["achievements.secrets"] ? true : rank !== "$")
|
||||
.filter(({ rank }) => ({ S: 5, A: 4, B: 3, C: 2, $: 1, X: 0 }[rank] >= { S: 5, A: 4, B: 3, C: 2, $: 1, X: 0 }[options["achievements.threshold"]]))
|
||||
.sort((a, b) => ({ S: 5, A: 4, B: 3, C: 2, $: 1, X: 0 }[b.rank] + b.progress * 0.99) - ({ S: 5, A: 4, B: 3, C: 2, $: 1, X: 0 }[a.rank] + a.progress * 0.99))
|
||||
.filter(({rank}) => options["achievements.secrets"] ? true : rank !== "$")
|
||||
.filter(({rank}) => ({S: 5, A: 4, B: 3, C: 2, $: 1, X: 0}[rank] >= {S: 5, A: 4, B: 3, C: 2, $: 1, X: 0}[options["achievements.threshold"]]))
|
||||
.sort((a, b) => ({S: 5, A: 4, B: 3, C: 2, $: 1, X: 0}[b.rank] + b.progress * 0.99) - ({S: 5, A: 4, B: 3, C: 2, $: 1, X: 0}[a.rank] + a.progress * 0.99))
|
||||
.slice(0, options["achievements.limit"] || Infinity),
|
||||
},
|
||||
})
|
||||
@@ -437,26 +437,26 @@
|
||||
sections: options["languages.sections"].split(", ").map(x => x.trim()).filter(x => /^(most-used|recently-used)$/.test(x)),
|
||||
details: options["languages.details"].split(",").map(x => x.trim()).filter(x => x),
|
||||
get colors() {
|
||||
return Object.fromEntries(Object.entries(this.favorites).map(([key, { color }]) => [key, color]))
|
||||
return Object.fromEntries(Object.entries(this.favorites).map(([key, {color}]) => [key, color]))
|
||||
},
|
||||
total: faker.datatype.number(10000),
|
||||
get stats() {
|
||||
return Object.fromEntries(Object.entries(this.favorites).map(([key, { value }]) => [key, value]))
|
||||
return Object.fromEntries(Object.entries(this.favorites).map(([key, {value}]) => [key, value]))
|
||||
},
|
||||
["stats.recent"]: {
|
||||
total: faker.datatype.number(10000),
|
||||
get lines() {
|
||||
return Object.fromEntries(Object.entries(this.favorites).map(([key, { value }]) => [key, value]))
|
||||
return Object.fromEntries(Object.entries(this.favorites).map(([key, {value}]) => [key, value]))
|
||||
},
|
||||
get stats() {
|
||||
return Object.fromEntries(Object.entries(this.favorites).map(([key, { value }]) => [key, value]))
|
||||
return Object.fromEntries(Object.entries(this.favorites).map(([key, {value}]) => [key, value]))
|
||||
},
|
||||
commits: faker.datatype.number(500),
|
||||
files: faker.datatype.number(1000),
|
||||
days: Number(options["languages.recent.days"]),
|
||||
},
|
||||
favorites: distribution(7).map((value, index, array) => ({ name: faker.lorem.word(), color: faker.internet.color(), value, size: faker.datatype.number(1000000), x: array.slice(0, index).reduce((a, b) => a + b, 0) })),
|
||||
recent: distribution(7).map((value, index, array) => ({ name: faker.lorem.word(), color: faker.internet.color(), value, size: faker.datatype.number(1000000), x: array.slice(0, index).reduce((a, b) => a + b, 0) })),
|
||||
favorites: distribution(7).map((value, index, array) => ({name: faker.lorem.word(), color: faker.internet.color(), value, size: faker.datatype.number(1000000), x: array.slice(0, index).reduce((a, b) => a + b, 0)})),
|
||||
recent: distribution(7).map((value, index, array) => ({name: faker.lorem.word(), color: faker.internet.color(), value, size: faker.datatype.number(1000000), x: array.slice(0, index).reduce((a, b) => a + b, 0)})),
|
||||
},
|
||||
})
|
||||
: null),
|
||||
@@ -536,7 +536,7 @@
|
||||
},
|
||||
},
|
||||
},
|
||||
indents: { style: "spaces", spaces: 1, tabs: 0 },
|
||||
indents: {style: "spaces", spaces: 1, tabs: 0},
|
||||
linguist: {
|
||||
available: true,
|
||||
get ordered() {
|
||||
@@ -554,7 +554,7 @@
|
||||
? ({
|
||||
get people() {
|
||||
const types = options["people.types"].split(",").map(x => x.trim())
|
||||
.map(x => ({ followed: "following", sponsors: "sponsorshipsAsMaintainer", sponsored: "sponsorshipsAsSponsor", sponsoring: "sponsorshipsAsSponsor" })[x] ?? x)
|
||||
.map(x => ({followed: "following", sponsors: "sponsorshipsAsMaintainer", sponsored: "sponsorshipsAsSponsor", sponsoring: "sponsorshipsAsSponsor"})[x] ?? x)
|
||||
.filter(x => ["followers", "following", "sponsorshipsAsMaintainer", "sponsorshipsAsSponsor"].includes(x))
|
||||
return {
|
||||
types,
|
||||
@@ -598,8 +598,8 @@
|
||||
data: new Array(12).fill(null).map(_ => ({
|
||||
timeUTCHumanReadable: `${new Date().getUTCHours()}:${new Date().getUTCMinutes()}`,
|
||||
color: faker.random.arrayElement(["#9be9a8", "#40c463", "#30a14e", "#216e39"]),
|
||||
sgv: faker.datatype.number({ min: 40, max: 400 }),
|
||||
delta: faker.datatype.number({ min: -10, max: 10 }),
|
||||
sgv: faker.datatype.number({min: 40, max: 400}),
|
||||
delta: faker.datatype.number({min: -10, max: 10}),
|
||||
direction: faker.random.arrayElement(["SingleUp", "DoubleUp", "FortyFiveUp", "Flat", "FortyFiveDown", "SingleDown", "DoubleDown"]),
|
||||
alert: faker.random.arrayElement(["Normal", "Urgent High", "Urgent Low", "High", "Low"]),
|
||||
arrowHumanReadable: faker.random.arrayElement(["↑↑", "↑", "↗", "→", "↘", "↓", "↓↓"]),
|
||||
@@ -611,9 +611,9 @@
|
||||
...(set.plugins.enabled.fortune
|
||||
? ({
|
||||
fortune: faker.random.arrayElement([
|
||||
{ chance: .06, color: "#43FD3B", text: "Good news will come to you by mail" },
|
||||
{ chance: .06, color: "#00CBB0", text: "キタ━━━━━━(゚∀゚)━━━━━━ !!!!" },
|
||||
{ chance: 0.03, color: "#FD4D32", text: "Excellent Luck" },
|
||||
{chance: .06, color: "#43FD3B", text: "Good news will come to you by mail"},
|
||||
{chance: .06, color: "#00CBB0", text: "キタ━━━━━━(゚∀゚)━━━━━━ !!!!"},
|
||||
{chance: 0.03, color: "#FD4D32", text: "Excellent Luck"},
|
||||
]),
|
||||
})
|
||||
: null),
|
||||
@@ -624,10 +624,10 @@
|
||||
url: options["pagespeed.url"] || "(attached website url)",
|
||||
detailed: options["pagespeed.detailed"] || false,
|
||||
scores: [
|
||||
{ score: faker.datatype.float({ max: 1 }), title: "Performance" },
|
||||
{ score: faker.datatype.float({ max: 1 }), title: "Accessibility" },
|
||||
{ score: faker.datatype.float({ max: 1 }), title: "Best Practices" },
|
||||
{ score: faker.datatype.float({ max: 1 }), title: "SEO" },
|
||||
{score: faker.datatype.float({max: 1}), title: "Performance"},
|
||||
{score: faker.datatype.float({max: 1}), title: "Accessibility"},
|
||||
{score: faker.datatype.float({max: 1}), title: "Best Practices"},
|
||||
{score: faker.datatype.float({max: 1}), title: "SEO"},
|
||||
],
|
||||
metrics: {
|
||||
observedFirstContentfulPaint: faker.datatype.number(500),
|
||||
@@ -639,12 +639,12 @@
|
||||
maxPotentialFID: faker.datatype.number(500),
|
||||
observedLoad: faker.datatype.number(500),
|
||||
firstMeaningfulPaint: faker.datatype.number(500),
|
||||
observedCumulativeLayoutShift: faker.datatype.float({ max: 1 }),
|
||||
observedCumulativeLayoutShift: faker.datatype.float({max: 1}),
|
||||
observedSpeedIndex: faker.datatype.number(1000),
|
||||
observedSpeedIndexTs: faker.time.recent(),
|
||||
observedTimeOriginTs: faker.time.recent(),
|
||||
observedLargestContentfulPaint: faker.datatype.number(1000),
|
||||
cumulativeLayoutShift: faker.datatype.float({ max: 1 }),
|
||||
cumulativeLayoutShift: faker.datatype.float({max: 1}),
|
||||
observedFirstPaintTs: faker.time.recent(),
|
||||
observedTraceEndTs: faker.time.recent(),
|
||||
largestContentfulPaint: faker.datatype.number(2000),
|
||||
@@ -698,14 +698,14 @@
|
||||
? ({
|
||||
discussions: {
|
||||
categories: {
|
||||
stats: { "🙏 Q&A": faker.datatype.number(100), "📣 Announcements": faker.datatype.number(100), "💡 Ideas": faker.datatype.number(100), "💬 General": faker.datatype.number(100) },
|
||||
stats: {"🙏 Q&A": faker.datatype.number(100), "📣 Announcements": faker.datatype.number(100), "💡 Ideas": faker.datatype.number(100), "💬 General": faker.datatype.number(100)},
|
||||
favorite: "📣 Announcements",
|
||||
},
|
||||
upvotes: { discussions: faker.datatype.number(1000), comments: faker.datatype.number(1000) },
|
||||
upvotes: {discussions: faker.datatype.number(1000), comments: faker.datatype.number(1000)},
|
||||
started: faker.datatype.number(1000),
|
||||
comments: faker.datatype.number(1000),
|
||||
answers: faker.datatype.number(1000),
|
||||
display: { categories: options["discussions.categories"] ? { limit: options["discussions.categories.limit"] || Infinity } : null },
|
||||
display: {categories: options["discussions.categories"] ? {limit: options["discussions.categories.limit"] || Infinity} : null},
|
||||
},
|
||||
})
|
||||
: null),
|
||||
@@ -730,7 +730,7 @@
|
||||
? ({
|
||||
topics: {
|
||||
mode: options["topics.mode"],
|
||||
type: { starred: "labels", labels: "labels", mastered: "icons", icons: "icons" }[options["topics.mode"]] || "labels",
|
||||
type: {starred: "labels", labels: "labels", mastered: "icons", icons: "icons"}[options["topics.mode"]] || "labels",
|
||||
list: new Array(Number(options["topics.limit"]) || 20).fill(null).map(_ => ({
|
||||
name: faker.lorem.words(2),
|
||||
description: faker.lorem.sentence(),
|
||||
@@ -759,8 +759,8 @@
|
||||
totalCount: faker.datatype.number(100),
|
||||
},
|
||||
stargazerCount: faker.datatype.number(10000),
|
||||
licenseInfo: { nickname: null, name: "MIT License" },
|
||||
primaryLanguage: { color: "#f1e05a", name: "JavaScript" },
|
||||
licenseInfo: {nickname: null, name: "MIT License"},
|
||||
primaryLanguage: {color: "#f1e05a", name: "JavaScript"},
|
||||
},
|
||||
starred: "1 day ago",
|
||||
},
|
||||
@@ -779,8 +779,8 @@
|
||||
totalCount: faker.datatype.number(100),
|
||||
},
|
||||
stargazerCount: faker.datatype.number(10000),
|
||||
licenseInfo: { nickname: null, name: "License" },
|
||||
primaryLanguage: { color: faker.internet.color(), name: faker.lorem.word() },
|
||||
licenseInfo: {nickname: null, name: "License"},
|
||||
primaryLanguage: {color: faker.internet.color(), name: faker.lorem.word()},
|
||||
},
|
||||
starred: `${i + 2} days ago`,
|
||||
})),
|
||||
@@ -825,8 +825,8 @@
|
||||
totalCount: faker.datatype.number(100),
|
||||
},
|
||||
stargazerCount: faker.datatype.number(10000),
|
||||
licenseInfo: { nickname: null, name: "License" },
|
||||
primaryLanguage: { color: faker.internet.color(), name: faker.lorem.word() },
|
||||
licenseInfo: {nickname: null, name: "License"},
|
||||
primaryLanguage: {color: faker.internet.color(), name: faker.lorem.word()},
|
||||
})),
|
||||
},
|
||||
})
|
||||
@@ -861,7 +861,7 @@
|
||||
for (let d = -14; d <= 0; d++) {
|
||||
const date = new Date(Date.now() - d * 24 * 60 * 60 * 1000).toISOString().substring(0, 10)
|
||||
dates.push(date)
|
||||
result.total.dates[date] = (total += (result.increments.dates[date] = faker.datatype.number(100)))
|
||||
result.total.dates[date] = total += result.increments.dates[date] = faker.datatype.number(100)
|
||||
}
|
||||
return result
|
||||
},
|
||||
@@ -884,13 +884,13 @@
|
||||
percents -= result.percent
|
||||
result.percent /= 100
|
||||
}
|
||||
results.filter(({ name }) => elements.includes(name) ? false : (elements.push(name), true))
|
||||
results.filter(({name}) => elements.includes(name) ? false : (elements.push(name), true))
|
||||
return results.sort((a, b) => b.percent - a.percent)
|
||||
}
|
||||
return {
|
||||
sections: options["wakatime.sections"].split(",").map(x => x.trim()).filter(x => x),
|
||||
days: Number(options["wakatime.days"]) || 7,
|
||||
time: { total: faker.datatype.number(100000), daily: faker.datatype.number(24) },
|
||||
time: {total: faker.datatype.number(100000), daily: faker.datatype.number(24)},
|
||||
editors: stats(["VS Code", "Chrome", "IntelliJ", "PhpStorm", "WebStorm", "Android Studio", "Visual Studio", "Sublime Text", "PyCharm", "Vim", "Atom", "Xcode"]),
|
||||
languages: stats(["JavaScript", "TypeScript", "PHP", "Java", "Python", "Vue.js", "HTML", "C#", "JSON", "Dart", "SCSS", "Kotlin", "JSX", "Go", "Ruby", "YAML"]),
|
||||
projects: stats(),
|
||||
@@ -909,16 +909,16 @@
|
||||
count: faker.datatype.number(1000),
|
||||
minutesWatched: faker.datatype.number(100000),
|
||||
episodesWatched: faker.datatype.number(10000),
|
||||
genres: new Array(4).fill(null).map(_ => ({ genre: faker.lorem.word() })),
|
||||
genres: new Array(4).fill(null).map(_ => ({genre: faker.lorem.word()})),
|
||||
},
|
||||
manga: {
|
||||
count: faker.datatype.number(1000),
|
||||
chaptersRead: faker.datatype.number(100000),
|
||||
volumesRead: faker.datatype.number(10000),
|
||||
genres: new Array(4).fill(null).map(_ => ({ genre: faker.lorem.word() })),
|
||||
genres: new Array(4).fill(null).map(_ => ({genre: faker.lorem.word()})),
|
||||
},
|
||||
},
|
||||
genres: new Array(4).fill(null).map(_ => ({ genre: faker.lorem.word() })),
|
||||
genres: new Array(4).fill(null).map(_ => ({genre: faker.lorem.word()})),
|
||||
},
|
||||
get lists() {
|
||||
const media = type => ({
|
||||
@@ -929,7 +929,7 @@
|
||||
genres: new Array(6).fill(null).map(_ => faker.lorem.word()),
|
||||
progress: faker.datatype.number(100),
|
||||
description: faker.lorem.paragraphs(),
|
||||
scores: { user: faker.datatype.number(100), community: faker.datatype.number(100) },
|
||||
scores: {user: faker.datatype.number(100), community: faker.datatype.number(100)},
|
||||
released: 100 + faker.datatype.number(1000),
|
||||
artwork: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
|
||||
})
|
||||
@@ -939,16 +939,16 @@
|
||||
...(medias.includes("anime")
|
||||
? {
|
||||
anime: {
|
||||
...(sections.includes("watching") ? { watching: new Array(Number(options["anilist.limit"]) || 4).fill(null).map(_ => media("ANIME")) } : {}),
|
||||
...(sections.includes("favorites") ? { favorites: new Array(Number(options["anilist.limit"]) || 4).fill(null).map(_ => media("ANIME")) } : {}),
|
||||
...(sections.includes("watching") ? {watching: new Array(Number(options["anilist.limit"]) || 4).fill(null).map(_ => media("ANIME"))} : {}),
|
||||
...(sections.includes("favorites") ? {favorites: new Array(Number(options["anilist.limit"]) || 4).fill(null).map(_ => media("ANIME"))} : {}),
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(medias.includes("manga")
|
||||
? {
|
||||
manga: {
|
||||
...(sections.includes("reading") ? { reading: new Array(Number(options["anilist.limit"]) || 4).fill(null).map(_ => media("MANGA")) } : {}),
|
||||
...(sections.includes("favorites") ? { favorites: new Array(Number(options["anilist.limit"]) || 4).fill(null).map(_ => media("MANGA")) } : {}),
|
||||
...(sections.includes("reading") ? {reading: new Array(Number(options["anilist.limit"]) || 4).fill(null).map(_ => media("MANGA"))} : {}),
|
||||
...(sections.includes("favorites") ? {favorites: new Array(Number(options["anilist.limit"]) || 4).fill(null).map(_ => media("MANGA"))} : {}),
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
@@ -974,7 +974,7 @@
|
||||
repo: `${faker.random.word()}/${faker.random.word()}`,
|
||||
size: 1,
|
||||
branch: "master",
|
||||
commits: [{ sha: faker.git.shortSha(), message: faker.lorem.sentence() }],
|
||||
commits: [{sha: faker.git.shortSha(), message: faker.lorem.sentence()}],
|
||||
timestamp: faker.date.recent(),
|
||||
},
|
||||
{
|
||||
@@ -1026,8 +1026,8 @@
|
||||
user: set.user,
|
||||
number: faker.datatype.number(100),
|
||||
title: faker.lorem.sentence(),
|
||||
lines: { added: faker.datatype.number(1000), deleted: faker.datatype.number(1000) },
|
||||
files: { changed: faker.datatype.number(10) },
|
||||
lines: {added: faker.datatype.number(1000), deleted: faker.datatype.number(1000)},
|
||||
files: {changed: faker.datatype.number(10)},
|
||||
timestamp: faker.date.recent(),
|
||||
},
|
||||
{
|
||||
@@ -1061,13 +1061,13 @@
|
||||
{
|
||||
type: "ref/create",
|
||||
repo: `${faker.random.word()}/${faker.random.word()}`,
|
||||
ref: { name: faker.lorem.slug(), type: faker.random.arrayElement(["tag", "branch"]) },
|
||||
ref: {name: faker.lorem.slug(), type: faker.random.arrayElement(["tag", "branch"])},
|
||||
timestamp: faker.date.recent(),
|
||||
},
|
||||
{
|
||||
type: "ref/delete",
|
||||
repo: `${faker.random.word()}/${faker.random.word()}`,
|
||||
ref: { name: faker.lorem.slug(), type: faker.random.arrayElement(["tag", "branch"]) },
|
||||
ref: {name: faker.lorem.slug(), type: faker.random.arrayElement(["tag", "branch"])},
|
||||
timestamp: faker.date.recent(),
|
||||
},
|
||||
{
|
||||
@@ -1096,7 +1096,7 @@
|
||||
...(set.plugins.enabled.isocalendar
|
||||
? ({
|
||||
isocalendar: {
|
||||
streak: { max: 30 + faker.datatype.number(20), current: faker.datatype.number(30) },
|
||||
streak: {max: 30 + faker.datatype.number(20), current: faker.datatype.number(30)},
|
||||
max: 10 + faker.datatype.number(40),
|
||||
average: faker.datatype.float(10),
|
||||
svg: await staticPlaceholder(set.plugins.enabled.isocalendar, `isocalendar.${options["isocalendar.duration"]}.svg`),
|
||||
@@ -1108,8 +1108,8 @@
|
||||
...(set.plugins.enabled.support
|
||||
? ({
|
||||
support: {
|
||||
stats: { solutions: faker.datatype.number(100), posts: faker.datatype.number(1000), topics: faker.datatype.number(1000), received: faker.datatype.number(1000), hearts: faker.datatype.number(1000) },
|
||||
badges: { uniques: [], multiples: [], count: faker.datatype.number(1000) },
|
||||
stats: {solutions: faker.datatype.number(100), posts: faker.datatype.number(1000), topics: faker.datatype.number(1000), received: faker.datatype.number(1000), hearts: faker.datatype.number(1000)},
|
||||
badges: {uniques: [], multiples: [], count: faker.datatype.number(1000)},
|
||||
},
|
||||
})
|
||||
: null),
|
||||
@@ -1200,20 +1200,20 @@
|
||||
}
|
||||
//Formatters
|
||||
data.f.bytes = function(n) {
|
||||
for (const { u, v } of [{ u: "E", v: 10 ** 18 }, { u: "P", v: 10 ** 15 }, { u: "T", v: 10 ** 12 }, { u: "G", v: 10 ** 9 }, { u: "M", v: 10 ** 6 }, { u: "k", v: 10 ** 3 }]) {
|
||||
for (const {u, v} of [{u: "E", v: 10 ** 18}, {u: "P", v: 10 ** 15}, {u: "T", v: 10 ** 12}, {u: "G", v: 10 ** 9}, {u: "M", v: 10 ** 6}, {u: "k", v: 10 ** 3}]) {
|
||||
if (n / v >= 1)
|
||||
return `${(n / v).toFixed(2).substr(0, 4).replace(/[.]0*$/, "")} ${u}B`
|
||||
}
|
||||
return `${n} byte${n > 1 ? "s" : ""}`
|
||||
}
|
||||
data.f.percentage = function(n, { rescale = true } = {}) {
|
||||
data.f.percentage = function(n, {rescale = true} = {}) {
|
||||
return `${
|
||||
(n * (rescale ? 100 : 1)).toFixed(2)
|
||||
.replace(/[.]([1-9]*)(0+)$/, (m, a, b) => `.${a}`)
|
||||
.replace(/[.]$/, "")
|
||||
}%`
|
||||
}
|
||||
data.f.ellipsis = function(text, { length = 20 } = {}) {
|
||||
data.f.ellipsis = function(text, {length = 20} = {}) {
|
||||
text = `${text}`
|
||||
if (text.length < length)
|
||||
return text
|
||||
@@ -1222,11 +1222,11 @@
|
||||
data.f.date = function(string, options) {
|
||||
if (options.date) {
|
||||
delete options.date
|
||||
Object.assign(options, { day: "numeric", month: "short", year: "numeric" })
|
||||
Object.assign(options, {day: "numeric", month: "short", year: "numeric"})
|
||||
}
|
||||
if (options.time) {
|
||||
delete options.time
|
||||
Object.assign(options, { hour: "2-digit", minute: "2-digit", second: "2-digit" })
|
||||
Object.assign(options, {hour: "2-digit", minute: "2-digit", second: "2-digit"})
|
||||
}
|
||||
return new Intl.DateTimeFormat("en-GB", options).format(new Date(string))
|
||||
}
|
||||
@@ -1234,7 +1234,7 @@
|
||||
return text?.name ?? text
|
||||
}
|
||||
//Render
|
||||
return await ejs.render(image, data, { async: true, rmWhitespace: true })
|
||||
return await ejs.render(image, data, {async: true, rmWhitespace: true})
|
||||
}
|
||||
//Reset globals contexts
|
||||
globalThis.placeholder.init = function(globals) {
|
||||
|
||||
Reference in New Issue
Block a user