24 Commits

Author SHA1 Message Date
a792791791 chore(deps): update dependency broadcast-channel to v3.7.0 2023-10-18 09:04:41 +00:00
126c709775 add forked from message
All checks were successful
deploy / deploy (push) Successful in 47s
2023-10-18 06:20:08 +01:00
52e71839c0 update readme
All checks were successful
deploy / deploy (push) Successful in 47s
2023-10-18 06:13:23 +01:00
c4b8354b36 remove yarn lock
Some checks failed
deploy / deploy (push) Has been cancelled
2023-10-18 06:12:48 +01:00
Lee
95c73dbb74 Merge pull request 'chore(deps): update dependency idb to v6.1.5' (#3) from renovate/idb-6.x-lockfile into master
All checks were successful
deploy / deploy (push) Successful in 47s
Reviewed-on: #3
2023-10-18 05:06:48 +00:00
36a0b0b826 make the navbar rounded
Some checks failed
deploy / deploy (push) Has been cancelled
2023-10-18 06:05:52 +01:00
b0adf848b4 chore(deps): update dependency idb to v6.1.5 2023-10-18 05:04:13 +00:00
6cbf0a9265 Merge branch 'master' of https://git.fascinated.cc/Fascinated/scoresaber-reloaded
All checks were successful
deploy / deploy (push) Successful in 48s
2023-10-18 05:57:26 +01:00
c07f82899c fix avatars not loading if the player doesn't have a avatar 2023-10-18 05:57:23 +01:00
Lee
bbce59047e Merge pull request 'Configure Renovate' (#1) from renovate/configure into master
All checks were successful
deploy / deploy (push) Successful in 47s
Reviewed-on: #1
2023-10-18 04:24:52 +00:00
de1987bfec move theme to folder
All checks were successful
deploy / deploy (push) Successful in 47s
2023-10-18 05:23:58 +01:00
49fa6dd451 remove filter button padding
All checks were successful
deploy / deploy (push) Successful in 48s
2023-10-18 05:18:52 +01:00
1dcef3d7e6 add some docs to the index file
All checks were successful
deploy / deploy (push) Successful in 48s
2023-10-18 05:17:25 +01:00
1f9fcc3759 update import and export data icons
All checks were successful
deploy / deploy (push) Successful in 47s
2023-10-18 05:14:06 +01:00
c32ef945ab update fontawesome 2023-10-18 05:13:56 +01:00
ed79e52441 update wording on twitch button
All checks were successful
deploy / deploy (push) Successful in 48s
2023-10-18 05:01:21 +01:00
06c09e8312 make it more obvious that you're already linked to twitch
All checks were successful
deploy / deploy (push) Successful in 48s
2023-10-18 04:58:23 +01:00
2ef9deedc3 maybe get twitch working?
All checks were successful
deploy / deploy (push) Successful in 48s
2023-10-18 04:52:37 +01:00
c2b5017324 add background image
All checks were successful
deploy / deploy (push) Successful in 48s
2023-10-18 04:39:49 +01:00
b2fe5751f1 make chart text white 2023-10-18 04:39:25 +01:00
1becf92a26 remove unneeded header in all requests
All checks were successful
deploy / deploy (push) Successful in 49s
2023-10-18 03:17:59 +01:00
375820c945 remove debug
All checks were successful
deploy / deploy (push) Successful in 47s
2023-10-18 03:15:49 +01:00
e9616c8d4c fix beatsaver api not being proxied
All checks were successful
deploy / deploy (push) Successful in 56s
2023-10-18 03:14:40 +01:00
248b2e70cf chore(deps): add renovate.json 2023-10-17 21:04:19 +00:00
24 changed files with 14107 additions and 1107 deletions

3
.gitignore vendored
View File

@ -2,4 +2,5 @@
.vscode
node_modules
public/build
build-info.js
build-info.js
yarn.lock

View File

@ -1,5 +1,7 @@
# ScoreSaber Reloaded
Forked from: <https://github.com/motzel/scoresaber-reloaded>
## Users
Just go to [ssr.fascinated.cc](https://ssr.fascinated.cc)
@ -9,11 +11,11 @@ Just go to [ssr.fascinated.cc](https://ssr.fascinated.cc)
### Install the dependencies
```bash
yarn install
npm install
```
### Start the dev environment
```bash
yarn dev
npm run dev
```

23
package-lock.json generated
View File

@ -371,17 +371,17 @@
}
},
"node_modules/broadcast-channel": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.6.0.tgz",
"integrity": "sha512-0x87tKJULniTOfECZP/LCsqWyMEbz0Oa+4yJ4i5dosOMxWUjx6mZ6nt9QmD2ox0r3MaCPojHrTQ2dj4ASZupeA==",
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz",
"integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.7.2",
"detect-node": "^2.1.0",
"js-sha3": "0.8.0",
"microseconds": "0.2.0",
"nano-time": "1.0.0",
"oblivious-set": "1.0.0",
"rimraf": "3.0.2",
"unload": "2.2.0"
}
@ -707,11 +707,10 @@
}
},
"node_modules/idb": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/idb/-/idb-6.1.2.tgz",
"integrity": "sha512-1DNDVu3yDhAZkFDlJf0t7r+GLZ248F5pTAtA7V0oVG3yjmV125qZOx3g0XpAEkGZVYQiFDAsSOnGet2bhugc3w==",
"dev": true,
"license": "ISC"
"version": "6.1.5",
"resolved": "https://registry.npmjs.org/idb/-/idb-6.1.5.tgz",
"integrity": "sha512-IJtugpKkiVXQn5Y+LteyBCNk1N8xpGV3wWZk9EVtZWH8DYkjBn0bX1XnGP9RkyZF0sAcywa6unHqSWKe7q4LGw==",
"dev": true
},
"node_modules/immer": {
"version": "9.0.5",
@ -1114,6 +1113,12 @@
"node": ">=0.10.0"
}
},
"node_modules/oblivious-set": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
"integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==",
"dev": true
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

7970
public/assets/external/fontawesome/all.css vendored Normal file

File diff suppressed because it is too large Load Diff

5982
public/assets/external/fontawesome/all.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -7,6 +7,16 @@
transform: rotate(359deg);
}
}
.main-background {
display: none;
height: 100vh;
width: 100vw;
z-index: 0;
left: 0;
top: 0;
}
.tabs,
.pagination-previous,
.pagination-next,
@ -9705,8 +9715,6 @@ label.panel-block:hover {
padding: 3rem 1.5rem 6rem;
}
/*# sourceMappingURL=bulma.css.map */
:root {
--background: #222;
--foreground: #252525;

View File

@ -1,6 +1,6 @@
:root {
--background: #222;
--foreground: #252525;
--foreground: #2e2e2e;
--textColor: #eee;
--ppColour: #8992e8;
--alternate: #72a8ff;
@ -15,6 +15,8 @@
--color-behind: rgb(128, 0, 0);
--color-highlight: darkgreen;
--error: red;
--transparency: 0.95;
}
html {
@ -23,7 +25,6 @@ html {
body {
color: var(--textColor);
background-color: var(--background) !important;
margin: 0 auto;
padding: 0 1rem;
min-height: 100vh;
@ -36,10 +37,24 @@ select {
outline: none;
}
.main-background {
position: fixed;
display: block;
background: var(--background-image) !important;
filter: blur(4px) brightness(0.8);
background-size: cover !important;
}
.ssr-page-container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
border-radius: 6px;
position: relative;
opacity: var(--transparency);
}
.box {
@ -63,7 +78,7 @@ select {
height: 100%;
background-size: cover;
background-repeat: no-repeat;
background-image: url("./scoresaber-logo.svg");
background-image: url("/assets/scoresaber-logo.svg");
}
.beatsavior-icon {
@ -79,7 +94,7 @@ select {
height: 100%;
background-size: cover;
background-repeat: no-repeat;
background-image: url("./accsaber-logo.png");
background-image: url("/assets/accsaber-logo.png");
}
.grid-transition-helper {

View File

@ -6,18 +6,24 @@
<title>ScoreSaber Reloaded</title>
<!-- Internal Assets -->
<link rel="icon" type="image/png" href="/assets/favicon.png" />
<link rel="stylesheet" href="/assets/ss-bulma.css" />
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"
/>
<link rel="stylesheet" href="/assets/ssr.css?20210925" />
<link rel="stylesheet" href="/assets/theme/ss-bulma.css" />
<link rel="stylesheet" href="/assets/theme/ssr.css?20210925" />
<link rel="stylesheet" href="/build/bundle.css" />
<!-- External Assets -->
<script
src="/assets/external/fontawesome/all.js"
data-auto-replace-svg="nest"
></script>
<link rel="stylesheet" href="/assets/external/fontawesome/all.css" />
<!-- Scripts -->
<script src="/assets/swiped-events.min.js"></script>
<script defer src="/build/bundle.js"></script>
<!-- Embed Tags -->
<meta content="Scoresaber Reloaded" property="og:site_name" />
<meta content="SSR - Score Tracker" property="og:title" />
<meta

6
renovate.json Normal file
View File

@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>Fascinated/renovate-config"
]
}

View File

@ -14,7 +14,9 @@
import RankingPage from './pages/Ranking.svelte';
import SearchPage from './pages/Search.svelte';
import TwitchPage from './pages/Twitch.svelte';
import { configStore } from './stores/config';
import createContainerStore from './stores/container';
import { setGlobalCSSValue } from './utils/css';
// When SSR was built (eg: 1 hour ago)
export const buildDateAgo = moment(buildInfo.buildDate, "MMMM Do YYYY, h:mm:ss a").fromNow();
@ -27,12 +29,16 @@
setContext('pageContainer', containerStore);
$: if (mainEl) containerStore.observe(mainEl)
setGlobalCSSValue("background-image", "url(" + $configStore.preferences.backgroundImage + ")")
</script>
<div class="main-background" />
<Router {url}>
<Nav />
<main bind:this={mainEl}>
<main bind:this={mainEl}>
<div class="ssr-page-container">
<Route path="/u/:initialPlayerId/*initialParams" let:params>
<PlayerPage initialPlayerId={params.initialPlayerId} initialParams={params.initialParams}/>
@ -86,7 +92,7 @@
}
footer {
margin: 1rem 0;
padding: 1rem;
font-size: .75em;
text-align: center;
}

View File

@ -1,14 +1,22 @@
<script>
import {opt} from '../../utils/js'
import { opt } from '../../utils/js';
export let player;
$: avatar = opt(player, 'playerInfo.avatar')
const avatar = opt(player, 'playerInfo.avatar')
// TEMP WORKAROUND UNTIL I MIGRATE TO NEW SS API
export let avatarr;
if (avatar.includes("oculus")) {
avatarr = "https://cdn.scoresaber.com/avatars/oculus.png"
} else {
avatarr = `https://cdn.scoresaber.com/avatars/${player.playerId}.jpg`
}
</script>
{#if avatar}
{#if avatarr}
<figure class="image is-24x24" on:click>
<img src={avatar} alt=""/>
<img src={avatarr} alt=""/>
</figure>
{/if}

View File

@ -1,23 +1,24 @@
<script>
import produce from 'immer'
import {configStore, DEFAULT_LOCALE, getSupportedLocales} from '../../stores/config'
import createTwitchService from '../../services/twitch'
import {ROUTER} from 'svelte-routing/src/contexts'
import {getContext, onMount} from 'svelte'
import {opt} from '../../utils/js'
import eventBus from '../../utils/broadcast-channel-pubsub'
import {DAY} from '../../utils/date'
import {exportJsonData, importDataHandler} from '../../utils/export-import'
import Dialog from '../Common/Dialog.svelte'
import Button from '../Common/Button.svelte'
import File from '../Common/File.svelte'
import Select from "./Select.svelte"
import produce from 'immer';
import { getContext, onMount } from 'svelte';
import { ROUTER } from 'svelte-routing/src/contexts';
import createTwitchService from '../../services/twitch';
import { DEFAULT_LOCALE, configStore, getSupportedLocales } from '../../stores/config';
import eventBus from '../../utils/broadcast-channel-pubsub';
import { DAY } from '../../utils/date';
import { exportJsonData, importDataHandler } from '../../utils/export-import';
import { opt } from '../../utils/js';
import Button from '../Common/Button.svelte';
import Dialog from '../Common/Dialog.svelte';
import File from '../Common/File.svelte';
import Select from "./Select.svelte";
export let show = false;
const DEFAULT_SCORE_COMPARISON_METHOD = 'in-place';
const DEFAULT_SECONDARY_PP_METRICS = 'attribution';
const DEFAULT_AVATAR_ICONS = 'only-if-needed';
const DEFAULT_BACKGROUND_IMAGE = "/assets/background.png";
let twitchToken = null;
@ -45,12 +46,14 @@
let currentScoreComparisonMethod = DEFAULT_SCORE_COMPARISON_METHOD;
let currentSecondaryPpMetrics = DEFAULT_SECONDARY_PP_METRICS;
let currentAvatarIcons = DEFAULT_AVATAR_ICONS;
let currentBackgroundImage = DEFAULT_BACKGROUND_IMAGE;
function onConfigUpdated(config) {
if (config?.locale) currentLocale = config.locale;
if (config?.scoreComparison) currentScoreComparisonMethod = config?.scoreComparison?.method ?? DEFAULT_SCORE_COMPARISON_METHOD;
if (config?.preferences?.secondaryPp) currentSecondaryPpMetrics = config?.preferences?.secondaryPp ?? DEFAULT_SECONDARY_PP_METRICS;
if (config?.preferences?.avatarIcons) currentAvatarIcons = config?.preferences?.avatarIcons ?? DEFAULT_AVATAR_ICONS;
if (config?.preferences?.backgroundImage) currentBackgroundImage = config?.preferences?.backgroundImage ?? DEFAULT_BACKGROUND_IMAGE;
}
function onSave() {
@ -61,6 +64,7 @@
draft.scoreComparison.method = currentScoreComparisonMethod;
draft.preferences.secondaryPp = currentSecondaryPpMetrics;
draft.preferences.avatarIcons = currentAvatarIcons;
draft.preferences.backgroundImage = currentBackgroundImage;
})
show = false;
@ -72,6 +76,7 @@
currentScoreComparisonMethod = $configStore.scoreComparison.method;
currentSecondaryPpMetrics = $configStore.preferences.secondaryPp;
currentAvatarIcons = $configStore.preferences.avatarIcons;
currentBackgroundImage = $configStore.preferences.backgroundImage;
}
show = false;
@ -90,7 +95,16 @@
showTwitchLinkBtn = !twitchToken || tokenExpireSoon;
twitchBtnLabel = !twitchToken || !tokenExpireSoon ? 'Link to Twitch' : 'Renew Twitch token'
if (!twitchToken) {
twitchBtnLabel = "Login with Twitch";
}
if (tokenExpireSoon) {
twitchBtnLabel = "Renew Twitch token"
}
if (twitchToken) {
twitchBtnLabel = "Already logged in"
}
twitchBtnTitle = twitchToken && tokenExpireInDays > 0 ? `Days left: ${tokenExpireInDays}` : null;
twitchBtnDisabled = !tokenExpireSoon;
}
@ -198,6 +212,11 @@
label={twitchBtnLabel} title={twitchBtnTitle}
on:click={() => window.location.href = twitchService.getAuthUrl(opt($activeRoute, 'uri', ''))}/>
</section>
<section class="option">
<label title="Change the image in the background of the site">Background Image</label>
<input bind:value={currentBackgroundImage} />
</section>
</section>
{:else}
Loading...
@ -205,9 +224,9 @@
</svelte:fragment>
<svelte:fragment slot="footer-left">
<File iconFa="fas fa-file-export" title="Import SSR data from file" loading={isImporting} disabled={isImporting}
<File iconFa="fa-solid fa-file-import" title="Import SSR data from file" loading={isImporting} disabled={isImporting}
accept="application/json" bind:this={importBtn} on:change={onImport}/>
<Button iconFa="fas fa-file-import" title="Export SSR data to file" on:click={onExport} loading={isExporting} disabled={isExporting}/>
<Button iconFa="fa-regular fa-floppy-disk" title="Export SSR data to file" on:click={onExport} loading={isExporting} disabled={isExporting}/>
</svelte:fragment>
<svelte:fragment slot="footer-right">

View File

@ -1,5 +1,6 @@
<script>
import Spinner from '../Common/Spinner.svelte'
import { SS_CDN_HOST } from '../../network/queues/scoresaber/page-queue';
import Spinner from '../Common/Spinner.svelte';
export let playerInfo;
export let isLoading = false;
@ -10,7 +11,8 @@
<span class="no-image">?</span>
{#if playerInfo && playerInfo.avatar}
<img src={playerInfo.avatar} class="avatar" alt="" />
<!-- TEMP WORKAROUND UNTIL I MIGRATE TO NEW SS API -->
<img src={playerInfo.avatar.replace("https://new.scoresaber.com/api/static", SS_CDN_HOST)} class="avatar" alt="" />
{/if}
<span class="spinner">
<Spinner width="100%" height="100%"/>

View File

@ -1,21 +1,21 @@
<script>
import Chart from 'chart.js/auto'
import Chart from 'chart.js/auto';
import 'chartjs-adapter-luxon';
import {DateTime} from 'luxon';
import {getContext, onMount} from 'svelte'
import createPlayerService from '../../../services/scoresaber/player'
import createScoresService from '../../../services/scoresaber/scores'
import createBeatSaviorService from '../../../services/beatsavior'
import {formatNumber} from '../../../utils/format'
import { DateTime } from 'luxon';
import { getContext, onMount } from 'svelte';
import createBeatSaviorService from '../../../services/beatsavior';
import createPlayerService from '../../../services/scoresaber/player';
import createScoresService from '../../../services/scoresaber/scores';
import eventBus from '../../../utils/broadcast-channel-pubsub';
import {
dateFromString,
formatDate,
formatDateWithOptions,
toSsMidnight,
} from '../../../utils/date'
import eventBus from '../../../utils/broadcast-channel-pubsub'
import {debounce} from '../../../utils/debounce'
import {onLegendClick} from './utils/legend-click-handler'
} from '../../../utils/date';
import { debounce } from '../../../utils/debounce';
import { formatNumber } from '../../../utils/format';
import { onLegendClick } from './utils/legend-click-handler';
export let playerId = null;
export let rankHistory = null;
@ -123,6 +123,7 @@
}
async function setupChart(hash, canvas) {
Chart.defaults.color = '#fff'; // Jank workaround to make the text white
if (!hash || !canvas || !rankHistory || !Object.keys(rankHistory).length || chartHash === lastHistoryHash) return;
lastHistoryHash = chartHash;
@ -134,7 +135,7 @@
const ppColor = "#007100";
const rankedPlayCountColor = "#3e3e3e";
const totalPlayCountColor = "#666";
const activityColor = "#333"
const activityColor = "#555"
const dtAccSaberToday = DateTime.fromJSDate(toSsMidnight(new Date()));
const dayTimestamps = Array(CHART_DAYS).fill(0).map((_, idx) => toSsMidnight(dtAccSaberToday.minus({days: CHART_DAYS - 1 - idx}).toJSDate()).getTime());

View File

@ -1,5 +1,5 @@
<script>
import {createEventDispatcher} from 'svelte'
import { createEventDispatcher } from 'svelte';
export let filter;
@ -71,7 +71,6 @@
right: 0;
width: 1.75em;
text-align: center;
padding: .4em;
transition: all 300ms ease-out;
background-color: var(--dimmed);
z-index: 1;

View File

@ -34,8 +34,6 @@
$: ssCoverUrl = hash ? `${SS_CDN_HOST}/covers/${encodeURIComponent(hash.toUpperCase())}.png` : null;
$: beatSaverCoverUrl = leaderboard?.beatMaps?.versions?.[0]?.coverURL ?? null;
console.log(leaderboard)
$: preloadImages([{url: ssCoverUrl, priority: 10}, {url: beatSaverCoverUrl, priority: 15}]);
$: coverUrl = loadedImages.length ? (loadedImages.sort((a, b) => a?.priority - b?.priority))[0].url : DEFAULT_IMG;

View File

@ -1,5 +1,4 @@
import { SsrDataFormatError } from "../others/errors";
import ssrConfig from "../ssr-config";
import { MINUTE } from "../utils/date";
import createNetworkCache from "./cache";
import {
@ -78,12 +77,8 @@ const setCacheIfNeeded = (response, cacheKey, cacheTtl) => {
export async function fetchUrl(url, options = {}, cors = true) {
try {
console.log(ssrConfig.name);
const response = await fetch(url, {
...options,
headers: {
"x-requested-with": ssrConfig.name,
},
...(cors ? { mode: "cors" } : null),
});

View File

@ -1,7 +1,8 @@
import { default as createQueue, PRIORITY } from "../http-queue";
import ssrConfig from "../../../ssr-config";
import { substituteVars } from "../../../utils/format";
import { default as createQueue, PRIORITY } from "../http-queue";
const BEATMAPS_API_URL = "https://api.beatsaver.com/";
const BEATMAPS_API_URL = ssrConfig.proxy + "/https://api.beatsaver.com";
const SONG_BY_HASH_URL = BEATMAPS_API_URL + "/maps/hash/${hash}";
const SONG_BY_KEY_URL = BEATMAPS_API_URL + "/maps/id/${key}";

View File

@ -1,8 +1,8 @@
import { default as createQueue, PRIORITY } from "../http-queue";
import ssrConfig from "../../../ssr-config";
import { substituteVars } from "../../../utils/format";
import { default as createQueue, PRIORITY } from "../http-queue";
const CLIENT_ID = "u0swxz56n4iumc634at1osoqdk31qt";
const CLIENT_ID = "r2phvaavwhzh2s19y72na3cq1x4a58";
const TWITCH_AUTH_URL = "https://id.twitch.tv/oauth2";
const AUTHORIZATION_URL =

View File

@ -1,11 +1,11 @@
import queues from "../network/queues/queues";
import keyValueRepository from "../db/repository/key-value";
import twitchRepository from "../db/repository/twitch";
import createPlayerService from "../services/scoresaber/player";
import profileApiClient from "../network/clients/twitch/api-profile";
import videosApiClient from "../network/clients/twitch/api-videos";
import { PRIORITY } from "../network/queues/http-queue";
import queues from "../network/queues/queues";
import createPlayerService from "../services/scoresaber/player";
import eventBus from "../utils/broadcast-channel-pubsub";
import log from "../utils/logger";
import {
addToDate,
dateFromString,
@ -14,7 +14,7 @@ import {
millisToDuration,
MINUTE,
} from "../utils/date";
import { PRIORITY } from "../network/queues/http-queue";
import log from "../utils/logger";
import makePendingPromisePool from "../utils/pending-promises";
const TWITCH_TOKEN_KEY = "twitchToken";

View File

@ -30,6 +30,7 @@ const DEFAULT_CONFIG = {
preferences: {
secondaryPp: "attribution",
avatarIcons: "only-if-needed",
backgroundImage: "/assets/background.png",
},
locale: DEFAULT_LOCALE,
};
@ -38,6 +39,7 @@ const newSettingsAvailableDefinition = {
"scoreComparison.method": "Method of displaying the comparison of scores",
"preferences.secondaryPp": "Setting the second PP metric",
"preferences.avatarIcons": "Showing icons on avatars",
"preferences.backgroundImage": "Change the background image",
locale: "Locale selection",
};

4
src/utils/css.js Normal file
View File

@ -0,0 +1,4 @@
export function setGlobalCSSValue(name, value) {
var r = document.querySelector(":root");
r.style.setProperty("--" + name, value);
}

1030
yarn.lock

File diff suppressed because it is too large Load Diff