Browse Source

Migrate to static icons colours

Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
John Molakvoæ 2 years ago
parent
commit
c59c3b5c1f

+ 5 - 5
apps/encryption/css/settings-personal.scss

@@ -2,14 +2,14 @@
  This file is licensed under the Affero General Public License version 3 or later.
  See the COPYING-README file. */
 
-#encryptAllError
-, #encryptAllSuccess
-, #recoveryEnabledError
-, #recoveryEnabledSuccess {
+#encryptAllError,
+#encryptAllSuccess,
+#recoveryEnabledError,
+#recoveryEnabledSuccess {
 	display: none;
 }
 
 /* icons for sidebar */
 .nav-icon-basic-encryption-module {
-	@include icon-color('app', 'encryption', $color-black);
+	background-image: var(--icon-encryption-dark);
 }

+ 2 - 2
apps/files/css/files.scss

@@ -133,7 +133,7 @@
 	@include icon-color('recent', 'files', $color-black);
 }
 .nav-icon-favorites {
-	@include icon-color('star-dark', 'actions', $color-black, 2, true);
+	@include icon-color('starred', 'actions', $color-black, 2, true);
 }
 .nav-icon-sharingin,
 .nav-icon-sharingout,
@@ -157,7 +157,7 @@
 	@include icon-color('unshare', 'files', $color-black);
 }
 .nav-icon-favorites-starred {
-	@include icon-color('star-dark', 'actions', $color-yellow, 2, true);
+	@include icon-color('starred', 'actions', $color-yellow, 2, true);
 }
 
 #app-navigation .nav-files a.nav-icon-files {

+ 1 - 1
apps/files_external/css/settings.scss

@@ -150,5 +150,5 @@
 }
 
 .nav-icon-external-storage {
-	@include icon-color('app-dark', 'files_external', $color-black);
+	background-image: var(--icon-external-dark);
 }

+ 11 - 4
apps/theming/src/UserThemes.vue

@@ -100,13 +100,12 @@ export default {
 			this.themes.forEach(theme => {
 				if (theme.id === id && enabled) {
 					theme.enabled = true
-					document.body.setAttribute(`data-theme-${theme.id}`, true)
 					return
 				}
 				theme.enabled = false
-				document.body.removeAttribute(`data-theme-${theme.id}`)
 			})
 
+			this.updateBodyAttributes()
 			this.selectItem(enabled, id)
 		},
 		changeFont({ enabled, id }) {
@@ -114,16 +113,24 @@ export default {
 			this.fonts.forEach(font => {
 				if (font.id === id && enabled) {
 					font.enabled = true
-					document.body.setAttribute(`data-theme-${font.id}`, true)
 					return
 				}
 				font.enabled = false
-				document.body.removeAttribute(`data-theme-${font.id}`)
 			})
 
+			this.updateBodyAttributes()
 			this.selectItem(enabled, id)
 		},
 
+		updateBodyAttributes() {
+			const enabledThemesIDs = this.themes.filter(theme => theme.enabled === true).map(theme => theme.id)
+			this.themes.forEach(theme => {
+				document.body.toggleAttribute(`data-theme-${theme.id}`, theme.enabled)
+			})
+
+			document.body.setAttribute('data-themes', enabledThemesIDs.join(','))
+		},
+
 		/**
 		 * Commit a change and force reload css
 		 * Fetching the file again will trigger the server update

+ 15 - 6
core/css/apps.scss

@@ -721,20 +721,16 @@ $min-content-width: $breakpoint-mobile - $navigation-width - $list-min-width;
 
 
 #app-settings-header .settings-button {
-	display: block;
+	display: flex;
+	align-items: center;
 	height: 44px;
 	width: 100%;
 	padding: 0;
 	margin: 0;
-	background-color: var(--color-main-background);
-	@include icon-color('settings-dark', 'actions', $color-black, 1, true);
-	background-position: 14px center;
-	background-repeat: no-repeat;
 	box-shadow: none;
 	border: 0;
 	border-radius: 0;
 	text-align: left;
-	padding-left: 44px;
 	font-weight: normal;
 	font-size: 100%;
 	opacity: 0.8;
@@ -750,6 +746,19 @@ $min-content-width: $breakpoint-mobile - $navigation-width - $list-min-width;
 	&:focus {
 		background-color: var(--color-background-hover);
 	}
+
+	&::before {	
+		background-image: var(--icon-settings-dark);
+		background-position: 14px center;
+		background-repeat: no-repeat;
+		content: '';
+		width: 44px;
+		height: 44px;
+		top: 0;
+		left: 0;
+		display: block;
+		filter: var(--background-invert-if-dark);
+	}
 }
 
 /* GENERAL SECTION ------------------------------------------------------------ */

+ 29 - 35
core/css/functions.scss

@@ -26,7 +26,7 @@
  * @param string $color The color
  * @return string The color without #
  */
-@function remove-hash-from-color($color) {
+ @function remove-hash-from-color($color) {
 	$color: unquote($color);
 	$index: str-index(inspect($color), '#');
 	@if $index {
@@ -36,22 +36,34 @@
 }
 
 /**
- * Calculates the URL to the svg under the SVG API.
- *
- * @param string $icon the icon filename
- * @param string $dir the icon folder within /core/img if $core or app name
- * @param string $color the desired color in hexadecimal
- * @param int [$version] the version of the file
- * @param bool [$core] search icon in core
- * @return string The URL to the svg.
+ * @see core/src/icons.js
  */
-@function icon-color-path($icon, $dir, $color, $version: 1, $core: false) {
-	$color: remove-hash-from-color($color);
-	@if $core {
-		@return '#{$webroot}/svg/core/#{$dir}/#{$icon}?color=#{$color}&v=#{$version}';
-	} @else {
-		@return '#{$webroot}/svg/#{$dir}/#{$icon}?color=#{$color}&v=#{$version}';
+@function match-color-string($color) {
+	@if $color == #000 {
+		@return "dark";
+	}
+	@if $color == #000 {
+		@return 'dark';
+	}
+	@if $color == #fff {
+		@return 'white';
+	}
+	@if $color == #FC0 {
+		@return 'yellow';
+	}
+	@if $color == #e9322d {
+		@return 'red';
+	}
+	@if $color == #eca700 {
+		@return 'orange';
 	}
+	@if $color == #46ba61 {
+		@return 'green';
+	}
+	@if $color == #969696 {
+		@return 'grey';
+	}
+	@return $color;
 }
 
 /**
@@ -66,30 +78,12 @@
  * @returns A background image with the url to the set to the requested icon.
  */
 @mixin icon-color($icon, $dir, $color, $version: 1, $core: false) {
-	$color: remove-hash-from-color($color);
+	$color: match-color-string($color);
 	/* $dir is the app name, so we add this to the icon var to avoid conflicts between apps */
-	$varName: "--icon-#{$dir}-#{$icon}-#{$color}";
-	@if $core {
-		$varName: "--icon-#{$icon}-#{$color}";
-	}
-	#{$varName}: url(icon-color-path($icon, $dir, $color, $version, $core));
+	$varName: "--icon-#{$icon}-#{$color}";
 	background-image: var(#{$varName});
 }
 
-/**
- * Create black and white icons
- * This will add a default black version of and an additional white version when .icon-white is applied
- */
-@mixin icon-black-white($icon, $dir, $version, $core: false) {
-	.icon-#{$icon} {
-		@include icon-color($icon, $dir, $color-black, $version, $core);
-	}
-	.icon-#{$icon}-white,
-	.icon-#{$icon}.icon-white {
-		@include icon-color($icon, $dir, $color-white, $version, $core);
-	}
-}
-
 @mixin position($value) {
 	@if $value == 'sticky' {
 		position: -webkit-sticky; // Safari support

+ 10 - 361
core/css/icons.scss

@@ -123,393 +123,42 @@ audio, canvas, embed, iframe, img, input, object, video {
 	}
 }
 
-/* ICONS -------------------------------------------------------------------
- * These icon classes are generated automatically with the following pattern
- * for icon-black-white('close', ...)
- * .icon-close (black icon)
- * .icon-close-white (white icon)
- * .icon-close.icon-white (white icon)
- *
- * Some class definitions are kept as before, since they don't follow the pattern
- * or have some additional styling like drop shadows
- */
-
-@include icon-black-white('add', 'actions', 1, true);
-@include icon-black-white('address', 'actions', 1, true);
-
-@include icon-black-white('audio', 'actions', 2, true);
 .icon-audio-white {
 	filter: drop-shadow(1px 1px 4px var(--color-box-shadow));
 }
 
-@include icon-black-white('audio-off', 'actions', 1, true);
 .icon-audio-off-white {
 	filter: drop-shadow(1px 1px 4px var(--color-box-shadow));
 }
 
-.icon-caret-white,
-.icon-caret {
-	@include icon-color('caret', 'actions', $color-white, 1, true);
-}
-
-.icon-caret-dark {
-	@include icon-color('caret', 'actions', $color-black, 1, true);
-}
-
-@include icon-black-white('checkmark', 'actions', 1, true);
-.icon-checkmark-color {
-	@include icon-color('checkmark', 'actions', $color-success, 1, true);
-}
-
-@include icon-black-white('clippy', 'actions', 2, true);
-@include icon-black-white('close', 'actions', 1, true);
-@include icon-black-white('comment', 'actions', 1, true);
-@include icon-black-white('confirm', 'actions', 2, true);
-@include icon-black-white('download', 'actions', 1, true);
-
-.icon-confirm-fade {
-	@include icon-color('confirm-fade', 'actions', $color-black, 2, true);
-}
-
-.icon-delete {
-	@include icon-color('delete', 'actions', $color-black, 1, true);
-	&.no-permission,
-	&.no-hover {
-		&:hover,
-		&:focus {
-			@include icon-color('delete', 'actions', $color-black, 1, true);
-		}
-	}
-	&:hover,
-	&:focus {
-		@include icon-color('delete', 'actions', $color-error, 1, true);
-		filter: initial;
-	}
-
-	&.icon-white {
-		@include icon-color('delete', 'actions', $color-white, 1, true);
-	}
-}
-
-.icon-delete-white {
-	@include icon-color('delete', 'actions', $color-white, 1, true);
-	&.no-permission {
-		&:hover,
-		&:focus {
-			@include icon-color('delete', 'actions', $color-white, 1, true);
-		}
-	}
-	&:hover,
-	&:focus {
-		@include icon-color('delete', 'actions', $color-error, 1, true);
-	}
-}
-
-@include icon-black-white('details', 'actions', 1, true);
-@include icon-black-white('edit', 'actions', 1, true);
-@include icon-black-white('error', 'actions', 1, true);
-
-.icon-error-color {
-	@include icon-color('error', 'actions', $color-error, 1, true);
-}
-@include icon-black-white('external', 'actions', 1, true);
-@include icon-black-white('fullscreen', 'actions', 1, true);
-
 .icon-fullscreen-white {
 	filter: drop-shadow(1px 1px 4px var(--color-box-shadow));
 }
 
-@include icon-black-white('history', 'actions', 2, true);
-@include icon-black-white('info', 'actions', 1, true);
-@include icon-black-white('logout', 'actions', 1, true);
-@include icon-black-white('mail', 'actions', 1, true);
-@include icon-black-white('menu', 'actions', 1, true);
-@include icon-black-white('menu-sidebar', 'actions', 1, true);
-@include icon-black-white('more', 'actions', 1, true);
-@include icon-black-white('password', 'actions', 1, true);
-@include icon-black-white('pause', 'actions', 1, true);
-@include icon-black-white('play', 'actions', 1, true);
-@include icon-black-white('play-add', 'actions', 1, true);
-@include icon-black-white('play-next', 'actions', 1, true);
-@include icon-black-white('play-previous', 'actions', 1, true);
-@include icon-black-white('projects', 'actions', 1, true);
-@include icon-black-white('public', 'actions', 1, true);
-@include icon-black-white('quota', 'actions', 1, true);
-@include icon-black-white('rename', 'actions', 1, true);
-@include icon-black-white('screen', 'actions', 1, true);
-@include icon-black-white('template-add', 'actions', 1, true);
-
 .icon-screen-white {
 	filter: drop-shadow(1px 1px 4px var(--color-box-shadow));
 }
 
-@include icon-black-white('screen-off', 'actions', 1, true);
 .icon-screen-off-white {
 	filter: drop-shadow(1px 1px 4px var(--color-box-shadow));
 }
 
-@include icon-black-white('search', 'actions', 1, true);
-
-/* default icon have a .5 opacity */
-.icon-settings {
-	@include icon-color('settings', 'actions', $color-black, 1, true);
-}
-
-.icon-settings-dark {
-	@include icon-color('settings-dark', 'actions', $color-black, 1, true);
-}
-
-.icon-settings-white {
-	@include icon-color('settings-dark', 'actions', $color-white, 1, true);
-}
-
-/* always use icon-shared, AdBlock blocks icon-share */
-.icon-shared,
-.icon-share {
-	@include icon-color('share', 'actions', $color-black, 1, true);
-	&.icon-white {
-		@include icon-color('share', 'actions', $color-white, 1, true);
-	}
-}
-.icon-shared-white,
-.icon-share-white {
-	@include icon-color('share', 'actions', $color-white, 1, true);
-}
-
-@include icon-black-white('sound', 'actions', 1, true);
-@include icon-black-white('sound-off', 'actions', 1, true);
-
-.icon-favorite {
-	@include icon-color('star-dark', 'actions', $color-black, 1, true);
-}
-
-@include icon-black-white('star', 'actions', 1, true);
-
-.icon-star-dark {
-	@include icon-color('star', 'actions', $color-black, 1, true);
-}
-
-.icon-starred {
-	&:hover,
-	&:focus {
-		@include icon-color('star', 'actions', $color-black, 1, true);
-	}
-	@include icon-color('star-dark', 'actions', $color-yellow, 1, true);
-}
-
-.icon-star {
-	&:hover,
-	&:focus {
-		@include icon-color('star-dark', 'actions', $color-yellow, 1, true);
-	}
-}
-
-@include icon-black-white('tag', 'actions', 2, true);
-@include icon-black-white('timezone', 'actions', 1, true);
-@include icon-black-white('toggle', 'actions', 1, true);
-@include icon-black-white('toggle-background', 'actions', 1, true);
-@include icon-black-white('toggle-pictures', 'actions', 1, true);
-@include icon-black-white('toggle-filelist', 'actions', 1, true);
-@include icon-black-white('triangle-e', 'actions', 1, true);
-@include icon-black-white('triangle-n', 'actions', 1, true);
-@include icon-black-white('triangle-s', 'actions', 1, true);
-@include icon-black-white('upload', 'actions', 1, true);
-@include icon-black-white('user', 'actions', 1, true);
-@include icon-black-white('group', 'actions', 1, true);
-@include icon-black-white('filter', 'actions', 1, true);
-
-@include icon-black-white('video', 'actions', 2, true);
 .icon-video-white {
 	filter: drop-shadow(1px 1px 4px var(--color-box-shadow));
 }
 
-@include icon-black-white('video-off', 'actions', 1, true);
 .icon-video-off-white {
 	filter: drop-shadow(1px 1px 4px var(--color-box-shadow));
 }
-@include icon-black-white('video-switch', 'actions', 1, true);
-
-/* SHADOW WHITE ICONS: white version only ----------------------------------- */
-.icon-view-close,
-.icon-view-close-white {
-	@include icon-color('view-close', 'actions', $color-white, 1, true);
-}
-.icon-view-download,
-.icon-view-download-white {
-	@include icon-color('view-download', 'actions', $color-white, 1, true);
-}
-.icon-view-pause,
-.icon-view-pause-white {
-	@include icon-color('view-pause', 'actions', $color-white, 1, true);
-}
-.icon-view-play,
-.icon-view-play-white {
-	@include icon-color('view-play', 'actions', $color-white, 1, true);
-}
 
-.icon-view-next {
-	@include icon-color('arrow-right', 'actions', $color-black, 1, true);
-	&.icon-white {
-		@include icon-color('arrow-right', 'actions', $color-white, 1, true);
-	}
-}
-
-
-.icon-view-previous {
-	@include icon-color('arrow-left', 'actions', $color-black, 1, true);
-	&.icon-white {
-		@include icon-color('arrow-left', 'actions', $color-white, 1, true);
-	}
-}
-
-
-@include icon-black-white('disabled-user', 'actions', 1, true);
-@include icon-black-white('disabled-users', 'actions', 1, true);
-@include icon-black-white('user-admin', 'actions', 1, true);
-
-@include icon-black-white('alert-outline', 'actions', 1, true);
-
-/* PLACES ------------------------------------------------------------------- */
-.icon-calendar {
-	@include icon-color('calendar', 'places', $color-white, 1, true);
-}
-
-.icon-calendar-dark {
-	@include icon-color('calendar', 'places', $color-black, 1, true);
-}
-
-.icon-contacts {
-	@include icon-color('contacts', 'places', $color-white, 1, true);
-}
-
-.icon-contacts-dark {
-	@include icon-color('contacts', 'places', $color-black, 1, true);
-}
-
-.icon-files {
-	@include icon-color('files', 'places', $color-white, 1, true);
-}
-
-.icon-files-dark {
-	@include icon-color('files', 'places', $color-black, 1, true);
-}
-
-.icon-file,
-.icon-filetype-text {
-	@include icon-color('text', 'filetypes', #969696, 1, true);
-}
-
-.icon-filetype-file {
-	@include icon-color('file', 'filetypes', #969696, 1, true);
-}
-
-@include icon-black-white('folder', 'filetypes', 1, true);
-.icon-filetype-folder {
-	@include icon-color('folder', 'filetypes', $color-primary, 1, true);
-}
-
-.icon-filetype-folder-drag-accept {
-	@include icon-color('folder-drag-accept', 'filetypes', $color-primary, 1, true);
-}
-
-
-@include icon-black-white('home', 'places', 1, true);
-@include icon-black-white('link', 'places', 1, true);
-@include icon-black-white('music', 'places', 1, true);
-@include icon-black-white('picture', 'places', 1, true);
-
-
-/* CLIENTS ------------------------------------------------------------------- */
-
-@include icon-black-white('desktop', 'clients', 1, true);
-@include icon-black-white('phone', 'clients', 1, true);
-@include icon-black-white('tablet', 'clients', 1, true);
-
-/* APP CATEGORIES ------------------------------------------------------------------- */
-.icon-category-installed {
-	@include icon-color('user', 'actions', $color-black, 1, true);
-}
-
-.icon-category-enabled {
-	@include icon-color('checkmark', 'actions', $color-black, 1, true);
-}
-
-.icon-category-disabled {
-	@include icon-color('close', 'actions', $color-black, 1, true);
-}
-
-.icon-category-app-bundles {
-	@include icon-color('bundles', 'categories', $color-black, 1, true);
-}
-
-.icon-category-updates {
-	@include icon-color('download', 'actions', $color-black, 1, true);
-}
-
-.icon-category-files {
-	@include icon-color('files', 'categories', $color-black, 1, true);
-}
-
-.icon-category-social {
-	@include icon-color('social', 'categories', $color-black, 1, true);
-}
-
-.icon-category-office {
-	@include icon-color('office', 'categories', $color-black, 1, true);
-}
-
-.icon-category-auth {
-	@include icon-color('auth', 'categories', $color-black, 1, true);
-}
-
-.icon-category-monitoring {
-	@include icon-color('monitoring', 'categories', $color-black, 1, true);
-}
-
-.icon-category-multimedia {
-	@include icon-color('multimedia', 'categories', $color-black, 1, true);
-}
-
-.icon-category-organization {
-	@include icon-color('organization', 'categories', $color-black, 1, true);
-}
-
-.icon-category-customization {
-	@include icon-color('customization', 'categories', $color-black, 1, true);
-}
-
-.icon-category-integration {
-	@include icon-color('integration', 'categories', $color-black, 1, true);
-}
-
-.icon-category-tools {
-	@include icon-color('settings-dark', 'actions', $color-black, 1, true);
-}
-
-.icon-category-games {
-	@include icon-color('games', 'categories', $color-black, 1, true);
-}
-
-.icon-category-security {
-	@include icon-color('password', 'actions', $color-black, 1, true);
-}
-
-.icon-category-search {
-	@include icon-color('search', 'actions', $color-black, 1, true);
-}
-
-.icon-category-workflow {
-	@include icon-color('workflow', 'categories', $color-black, 1, true);
-}
-
-.icon-category-dashboard {
-	@include icon-color('dashboard', 'categories', $color-black, 1, true);
-}
-
-.icon-talk {
-	@include icon-color('app-dark', 'spreed', $color-black, 1);
-}
+/* ICONS -------------------------------------------------------------------
+ * These icon classes are generated automatically with the following pattern
+ * .icon-close (black icon)
+ * .icon-close-white (white icon)
+ * .icon-close.icon-white (white icon)
+ *
+ * Some class definitions are kept as before, since they don't follow the pattern
+ * or have some additional styling like drop shadows
+ */
 
-.nav-icon-systemtagsfilter {
-	@include icon-color('tag', 'actions', $color-black, 1, true);
-}
+@import url('../../dist/icons.css');

+ 2 - 0
core/css/styles.scss

@@ -975,6 +975,8 @@ span.ui-icon {
 		background-size: 20px 20px;
 		padding: 14px;
 		cursor: pointer;
+		// Force white
+		background-image: var(--original-icon-contacts-white);
 		filter: var(--primary-invert-if-bright);
 
 		&:hover,

+ 1 - 0
core/img/actions/change.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" version="1.1" height="16"><path d="m8 2c-2.142 0-4.125 1.145-5.196 3l1.948 1.125c0.671-1.162 1.906-1.875 3.2476-1.875 1.1906 0 2.297 0.56157 3 1.5l-1.5 1.5h4.5v-4.5l-1.406 1.406c-1.129-1.348-2.802-2.1563-4.594-2.1563z"/><path d="m2 8.75v4.5l1.408-1.41c1.116 1.334 2.817 2.145 4.592 2.16 2.16 0.01827 4.116-1.132 5.196-3.002l-1.948-1.125c-0.677 1.171-1.9005 1.886-3.248 1.875-1.18-0.01-2.3047-0.572-3-1.5l1.5-1.5z"/></svg>

+ 1 - 0
core/img/actions/recent.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 16 16" height="16" width="16" version="1.1"><circle stroke-width="2" stroke="#000" cy="8" cx="8" r="7" fill="none"/><path stroke-linejoin="round" d="m8 3.5-1 5 3.5 2-2-2z" stroke="#000" stroke-linecap="round" stroke-width="1.5"/></svg>

+ 1 - 0
core/img/actions/unshare.svg

@@ -0,0 +1 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m12.5 1a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 0.003906 0.12891l-4.9023 2.4512a2.5 2.5 0 0 0-1.6016-0.58008 2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 0.30469-0.021484l3.4395-1.7246-1.25-0.625a2.5 2.5 0 0 0 0.0058594-0.12891 2.5 2.5 0 0 0-0.0039062-0.12891l4.9023-2.4512a2.5 2.5 0 0 0 1.6016 0.58008 2.5 2.5 0 0 0 0.26562-0.013672l1.5625-0.7832a2.5 2.5 0 0 0 0.67188-1.7031 2.5 2.5 0 0 0-2.5-2.5zm0.25391 9.0156-3.7246 1.8672 0.97656 0.48828a2.5 2.5 0 0 0-0.005859 0.12891 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5 2.5 2.5 0 0 0-2.2461-2.4844z"/><rect transform="rotate(-26.63)" x="-1.0586" y="11.891" width="11.687" height="2.0029" ry="0" style="paint-order:normal"/></svg>

+ 1 - 0
core/img/apps/circles.svg

@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 21.33 21.33" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M10.67 1.33a9.34 9.34 0 100 18.68 9.34 9.34 0 000-18.68zM6.93 15.8a2.33 2.33 0 110-4.67 2.33 2.33 0 010 4.67zm1.4-8.87a2.33 2.33 0 114.67 0 2.33 2.33 0 01-4.67 0zm6.07 8.87a2.33 2.33 0 110-4.67 2.33 2.33 0 010 4.67z"/></svg>

+ 335 - 0
core/src/icons.js

@@ -0,0 +1,335 @@
+/* eslint-disable quote-props */
+/* eslint-disable node/no-unpublished-import */
+import path from 'path'
+import fs from 'fs'
+import sass from 'sass'
+
+const colors = {
+	dark: '000',
+	white: 'fff',
+	yellow: 'FC0',
+	red: 'e9322d',
+	orange: 'eca700',
+	green: '46ba61',
+	grey: '969696',
+}
+
+const variables = {}
+const icons = {
+	'add': path.join(__dirname, '../img', 'actions', 'add.svg'),
+	'address': path.join(__dirname, '../img', 'actions', 'address.svg'),
+	'alert-outline': path.join(__dirname, '../img', 'actions', 'alert-outline.svg'),
+	'audio-off': path.join(__dirname, '../img', 'actions', 'audio-off.svg'),
+	'audio': path.join(__dirname, '../img', 'actions', 'audio.svg'),
+	'calendar': path.join(__dirname, '../img', 'places', 'calendar.svg'),
+	'caret': path.join(__dirname, '../img', 'actions', 'caret.svg'),
+	'category-app-bundles': path.join(__dirname, '../img', 'categories', 'bundles.svg'),
+	'category-auth': path.join(__dirname, '../img', 'categories', 'auth.svg'),
+	'category-customization': path.join(__dirname, '../img', 'categories', 'customization.svg'),
+	'category-dashboard': path.join(__dirname, '../img', 'categories', 'dashboard.svg'),
+	'category-files': path.join(__dirname, '../img', 'categories', 'files.svg'),
+	'category-games': path.join(__dirname, '../img', 'categories', 'games.svg'),
+	'category-integration': path.join(__dirname, '../img', 'categories', 'integration.svg'),
+	'category-monitoring': path.join(__dirname, '../img', 'categories', 'monitoring.svg'),
+	'category-multimedia': path.join(__dirname, '../img', 'categories', 'multimedia.svg'),
+	'category-office': path.join(__dirname, '../img', 'categories', 'office.svg'),
+	'category-organization': path.join(__dirname, '../img', 'categories', 'organization.svg'),
+	'category-social': path.join(__dirname, '../img', 'categories', 'social.svg'),
+	'category-workflow': path.join(__dirname, '../img', 'categories', 'workflow.svg'),
+	'change': path.join(__dirname, '../img', 'actions', 'change.svg'),
+	'checkmark': path.join(__dirname, '../img', 'actions', 'checkmark.svg'),
+	'circles': path.join(__dirname, '../img', 'apps', 'circles.svg'),
+	'clippy': path.join(__dirname, '../img', 'actions', 'clippy.svg'),
+	'close': path.join(__dirname, '../img', 'actions', 'close.svg'),
+	'comment': path.join(__dirname, '../img', 'actions', 'comment.svg'),
+	'confirm-fade': path.join(__dirname, '../img', 'actions', 'confirm-fade.svg'),
+	'confirm': path.join(__dirname, '../img', 'actions', 'confirm.svg'),
+	'contacts': path.join(__dirname, '../img', 'places', 'contacts.svg'),
+	'delete': path.join(__dirname, '../img', 'actions', 'delete.svg'),
+	'desktop': path.join(__dirname, '../img', 'clients', 'desktop.svg'),
+	'details': path.join(__dirname, '../img', 'actions', 'details.svg'),
+	'disabled-user': path.join(__dirname, '../img', 'actions', 'disabled-user.svg'),
+	'disabled-users': path.join(__dirname, '../img', 'actions', 'disabled-users.svg'),
+	'download': path.join(__dirname, '../img', 'actions', 'download.svg'),
+	'edit': path.join(__dirname, '../img', 'actions', 'edit.svg'),
+	'encryption': path.join(__dirname, '../../', 'apps/files_external/img', 'app.svg'),
+	'error': path.join(__dirname, '../img', 'actions', 'error.svg'),
+	'external': path.join(__dirname, '../img', 'actions', 'external.svg'),
+	'favorite': path.join(__dirname, '../img', 'actions', 'star-dark.svg'),
+	'files': path.join(__dirname, '../img', 'places', 'files.svg'),
+	'filter': path.join(__dirname, '../img', 'actions', 'filter.svg'),
+	'folder': path.join(__dirname, '../img', 'filetypes', 'folder.svg'),
+	'fullscreen': path.join(__dirname, '../img', 'actions', 'fullscreen.svg'),
+	'group': path.join(__dirname, '../img', 'actions', 'group.svg'),
+	'history': path.join(__dirname, '../img', 'actions', 'history.svg'),
+	'home': path.join(__dirname, '../img', 'places', 'home.svg'),
+	'info': path.join(__dirname, '../img', 'actions', 'info.svg'),
+	'link': path.join(__dirname, '../img', 'places', 'link.svg'),
+	'logout': path.join(__dirname, '../img', 'actions', 'logout.svg'),
+	'mail': path.join(__dirname, '../img', 'actions', 'mail.svg'),
+	'menu-sidebar': path.join(__dirname, '../img', 'actions', 'menu-sidebar.svg'),
+	'menu': path.join(__dirname, '../img', 'actions', 'menu.svg'),
+	'more': path.join(__dirname, '../img', 'actions', 'more.svg'),
+	'music': path.join(__dirname, '../img', 'places', 'music.svg'),
+	'password': path.join(__dirname, '../img', 'actions', 'password.svg'),
+	'pause': path.join(__dirname, '../img', 'actions', 'pause.svg'),
+	'phone': path.join(__dirname, '../img', 'clients', 'phone.svg'),
+	'picture': path.join(__dirname, '../img', 'places', 'picture.svg'),
+	'play-add': path.join(__dirname, '../img', 'actions', 'play-add.svg'),
+	'play-next': path.join(__dirname, '../img', 'actions', 'play-next.svg'),
+	'play-previous': path.join(__dirname, '../img', 'actions', 'play-previous.svg'),
+	'play': path.join(__dirname, '../img', 'actions', 'play.svg'),
+	'projects': path.join(__dirname, '../img', 'actions', 'projects.svg'),
+	'public': path.join(__dirname, '../img', 'actions', 'public.svg'),
+	'quota': path.join(__dirname, '../img', 'actions', 'quota.svg'),
+	'recent': path.join(__dirname, '../img', 'actions', 'recent.svg'),
+	'rename': path.join(__dirname, '../img', 'actions', 'rename.svg'),
+	'screen-off': path.join(__dirname, '../img', 'actions', 'screen-off.svg'),
+	'screen': path.join(__dirname, '../img', 'actions', 'screen.svg'),
+	'search': path.join(__dirname, '../img', 'actions', 'search.svg'),
+	'settings': path.join(__dirname, '../img', 'actions', 'settings-dark.svg'),
+	'share': path.join(__dirname, '../img', 'actions', 'share.svg'),
+	'shared': path.join(__dirname, '../img', 'actions', 'share.svg'),
+	'sound-off': path.join(__dirname, '../img', 'actions', 'sound-off.svg'),
+	'sound': path.join(__dirname, '../img', 'actions', 'sound.svg'),
+	'star': path.join(__dirname, '../img', 'actions', 'star.svg'),
+	'starred': path.join(__dirname, '../img', 'actions', 'star-dark.svg'),
+	'tablet': path.join(__dirname, '../img', 'clients', 'tablet.svg'),
+	'tag': path.join(__dirname, '../img', 'actions', 'tag.svg'),
+	'talk': path.join(__dirname, '../img', 'apps', 'spreed.svg'),
+	'template-add': path.join(__dirname, '../img', 'actions', 'template-add.svg'),
+	'timezone': path.join(__dirname, '../img', 'actions', 'timezone.svg'),
+	'toggle-background': path.join(__dirname, '../img', 'actions', 'toggle-background.svg'),
+	'toggle-filelist': path.join(__dirname, '../img', 'actions', 'toggle-filelist.svg'),
+	'toggle-pictures': path.join(__dirname, '../img', 'actions', 'toggle-pictures.svg'),
+	'toggle': path.join(__dirname, '../img', 'actions', 'toggle.svg'),
+	'triangle-e': path.join(__dirname, '../img', 'actions', 'triangle-e.svg'),
+	'triangle-n': path.join(__dirname, '../img', 'actions', 'triangle-n.svg'),
+	'triangle-s': path.join(__dirname, '../img', 'actions', 'triangle-s.svg'),
+	'unshare': path.join(__dirname, '../img', 'actions', 'unshare.svg'),
+	'upload': path.join(__dirname, '../img', 'actions', 'upload.svg'),
+	'user-admin': path.join(__dirname, '../img', 'actions', 'user-admin.svg'),
+	'user': path.join(__dirname, '../img', 'actions', 'user.svg'),
+	'video-off': path.join(__dirname, '../img', 'actions', 'video-off.svg'),
+	'video-switch': path.join(__dirname, '../img', 'actions', 'video-switch.svg'),
+	'video': path.join(__dirname, '../img', 'actions', 'video.svg'),
+	'view-close': path.join(__dirname, '../img', 'actions', 'view-close.svg'),
+	'view-download': path.join(__dirname, '../img', 'actions', 'view-download.svg'),
+	'view-next': path.join(__dirname, '../img', 'actions', 'arrow-right.svg'),
+	'view-pause': path.join(__dirname, '../img', 'actions', 'view-pause.svg'),
+	'view-play': path.join(__dirname, '../img', 'actions', 'view-play.svg'),
+	'view-previous': path.join(__dirname, '../img', 'actions', 'arrow-left.svg'),
+}
+
+const iconsColor = {
+	'settings': {
+		path: path.join(__dirname, '../img', 'actions', 'settings.svg'),
+		color: 'black',
+	},
+	'error-color': {
+		path: path.join(__dirname, '../img', 'actions', 'error.svg'),
+		color: 'red',
+	},
+	'checkmark-color': {
+		path: path.join(__dirname, '../img', 'actions', 'checkmark.svg'),
+		color: 'green',
+	},
+	'starred': {
+		path: path.join(__dirname, '../img', 'actions', 'star-dark.svg'),
+		color: 'yellow',
+	},
+	'delete-color': {
+		path: path.join(__dirname, '../img', 'actions', 'delete.svg'),
+		color: 'red',
+	},
+	'file': {
+		path: path.join(__dirname, '../img', 'filetypes', 'text.svg'),
+		color: 'grey',
+	},
+	'filetype-file': {
+		path: path.join(__dirname, '../img', 'filetypes', 'file.svg'),
+		color: 'grey',
+	},
+	'filetype-folder': {
+		path: path.join(__dirname, '../img', 'filetypes', 'folder.svg'),
+		// TODO: replace primary ?
+		color: 'primary',
+	},
+	'filetype-folder-drag-accept': {
+		path: path.join(__dirname, '../img', 'filetypes', 'folder-drag-accept.svg'),
+		// TODO: replace primary ?
+		color: 'primary',
+	},
+}
+
+// use this to define aliases to existing icons
+// key is the css selector, value is the variable
+const iconsAliases = {
+	'icon-caret': 'icon-caret-white',
+	// starring action
+	'icon-star:hover': 'icon-starred',
+	'icon-star:focus': 'icon-starred',
+	// Un-starring action
+	'icon-starred:hover': 'icon-star',
+	'icon-starred:focus': 'icon-star',
+	// Delete normal
+	'icon-delete.no-permission:hover': 'icon-delete-dark',
+	'icon-delete.no-permission:focus': 'icon-delete-dark',
+	'icon-delete.no-hover:hover': 'icon-delete-dark',
+	'icon-delete.no-hover:focus': 'icon-delete-dark',
+	'icon-delete:hover': 'icon-delete-color-red',
+	'icon-delete:focus': 'icon-delete-color-red',
+	// Delete white
+	'icon-delete-white.no-permission:hover': 'icon-delete-white',
+	'icon-delete-white.no-permission:focus': 'icon-delete-white',
+	'icon-delete-white.no-hover:hover': 'icon-delete-white',
+	'icon-delete-white.no-hover:focus': 'icon-delete-white',
+	'icon-delete-white:hover': 'icon-delete-color-red',
+	'icon-delete-white:focus': 'icon-delete-color-red',
+	// Default to white
+	'icon-view-close': 'icon-view-close-white',
+	'icon-view-download': 'icon-view-download-white',
+	'icon-view-pause': 'icon-view-pause-white',
+	'icon-view-play': 'icon-view-play-white',
+	// Default app place to white
+	'icon-calendar': 'icon-calendar-white',
+	'icon-contacts': 'icon-contacts-white',
+	'icon-files': 'icon-files-white',
+	// Re-using existing icons
+	'icon-category-installed': 'icon-user-dark',
+	'icon-category-enabled': 'icon-checkmark-dark',
+	'icon-category-disabled': 'icon-close-dark',
+	'icon-category-updates': 'icon-download-dark',
+	'icon-category-security': 'icon-password-dark',
+	'icon-category-search': 'icon-search-dark',
+	'icon-category-tools': 'icon-settings-dark',
+	'icon-filetype-text': 'icon-file-grey',
+}
+
+const colorSvg = function(svg = '', color = '000') {
+	if (!color.match(/^[0-9a-f]{3,6}$/i)) {
+		// Prevent not-sane colors from being written into the SVG
+		console.warn(color, 'does not match the required format')
+		color = '000'
+	}
+
+	// add fill (fill is not present on black elements)
+	const fillRe = /<((circle|rect|path)((?!fill)[a-z0-9 =".\-#():;,])+)\/>/gmi
+	svg = svg.replace(fillRe, '<$1 fill="#' + color + '"/>')
+
+	// replace any fill or stroke colors
+	svg = svg.replace(/stroke="#([a-z0-9]{3,6})"/gmi, 'stroke="#' + color + '"')
+	svg = svg.replace(/fill="#([a-z0-9]{3,6})"/gmi, 'fill="#' + color + '"')
+
+	return svg
+}
+
+const generateVariablesAliases = function(invert = false) {
+	let css = ''
+	Object.keys(variables).forEach(variable => {
+		if (variable.indexOf('original-') !== -1) {
+			let finalVariable = variable.replace('original-', '')
+			if (invert) {
+				finalVariable = finalVariable.replace('white', 'tempwhite')
+					.replace('dark', 'white')
+					.replace('tempwhite', 'dark')
+			}
+			css += `${finalVariable}: var(${variable});`
+		}
+	})
+	return css
+}
+
+const formatIcon = function(icon, invert = false) {
+	const color1 = invert ? 'white' : 'dark'
+	const color2 = invert ? 'dark' : 'white'
+	return `
+	.icon-${icon},
+	.icon-${icon}-dark {
+		background-image: var(--icon-${icon}-${color1});
+	}
+	.icon-${icon}-white,
+	.icon-${icon}.icon-white {
+		background-image: var(--icon-${icon}-${color2});
+	}`
+}
+const formatIconColor = function(icon) {
+	const { color } = iconsColor[icon]
+	return `
+	.icon-${icon} {
+		background-image: var(--icon-${icon}-${color});
+	}`
+}
+const formatAlias = function(alias, invert = false) {
+	let icon = iconsAliases[alias]
+	if (invert) {
+		icon = icon.replace('white', 'tempwhite')
+			.replace('dark', 'white')
+			.replace('tempwhite', 'dark')
+	}
+	return `
+	.${alias} {
+		background-image: var(--${icon})
+	}`
+}
+
+let css = ''
+Object.keys(icons).forEach(icon => {
+	const path = icons[icon]
+
+	const svg = fs.readFileSync(path, 'utf8')
+	const darkSvg = colorSvg(svg, '000000')
+	const whiteSvg = colorSvg(svg, 'ffffff')
+
+	variables[`--original-icon-${icon}-dark`] = Buffer.from(darkSvg, 'utf-8').toString('base64')
+	variables[`--original-icon-${icon}-white`] = Buffer.from(whiteSvg, 'utf-8').toString('base64')
+})
+
+Object.keys(iconsColor).forEach(icon => {
+	const { path, color } = iconsColor[icon]
+
+	const svg = fs.readFileSync(path, 'utf8')
+	const coloredSvg = colorSvg(svg, colors[color])
+	variables[`--icon-${icon}-${color}`] = Buffer.from(coloredSvg, 'utf-8').toString('base64')
+})
+
+
+// ICONS VARIABLES LIST
+css += ':root {'
+Object.keys(variables).forEach(variable => {
+	const data = variables[variable]
+	css += `${variable}: url(data:image/svg+xml;base64,${data});`
+})
+css += '}'
+
+// DEFAULT THEME
+css += 'body {'
+css += generateVariablesAliases()
+Object.keys(icons).forEach(icon => {
+	css += formatIcon(icon)
+})
+Object.keys(iconsColor).forEach(icon => {
+	css += formatIconColor(icon)
+})
+Object.keys(iconsAliases).forEach(alias => {
+	css += formatAlias(alias)
+})
+css += '}'
+
+// DARK THEME MEDIA QUERY
+css += '@media (prefers-color-scheme: dark) { body {'
+css += generateVariablesAliases(true)
+css += '}}'
+
+// DARK THEME
+css += 'body[data-themes*=light] {'
+css += generateVariablesAliases()
+css += '}'
+
+// DARK THEME
+css += 'body[data-themes*=dark] {'
+css += generateVariablesAliases(true)
+css += '}'
+
+// WRITE CSS
+fs.writeFileSync(path.join(__dirname, '../../dist', 'icons.css'), sass.compileString(css).css)

+ 1 - 1
core/src/jquery/css/jquery.ocdialog.scss

@@ -53,7 +53,7 @@
 	top: 0;
 	right: 0;
 	padding: 25px;
-	background: var(--icon-close-000) no-repeat center;
+	background: var(--icon-close-dark) no-repeat center;
 	opacity: .5;
 
 	&:hover,

+ 1 - 1
core/templates/layout.user.php

@@ -42,7 +42,7 @@ $getUserAvatar = static function (int $size) use ($_): string {
 	</head>
 	<body id="<?php p($_['bodyid']);?>" <?php foreach ($_['enabledThemes'] as $themeId) {
 				p("data-theme-$themeId ");
-			}?>>
+			}?> data-themes=<?php p(join(',', $_['enabledThemes'])) ?>>
 	<?php include 'layout.noscript.warning.php'; ?>
 
 		<?php foreach ($_['initialStates'] as $app => $initialState) { ?>

File diff suppressed because it is too large
+ 103 - 0
dist/icons.css


+ 0 - 1
lib/private/legacy/OC_Template.php

@@ -105,7 +105,6 @@ class OC_Template extends \OC\Template\Base {
 			// apps that started before the template initialization can load their own scripts/styles
 			// so to make sure this scripts/styles here are loaded first we put all core scripts first
 			// check lib/public/Util.php
-			// OC_Util::addStyle('css-variables', null, true);
 			OC_Util::addStyle('server', null, true);
 
 			// include common nextcloud webpack bundle

+ 446 - 63
package-lock.json

@@ -80,6 +80,7 @@
         "webdav": "^4.8.0"
       },
       "devDependencies": {
+        "@babel/node": "^7.17.10",
         "@nextcloud/babel-config": "^1.0.0",
         "@nextcloud/browserslist-config": "^2.2.0",
         "@nextcloud/eslint-config": "^7.0.2",
@@ -576,6 +577,29 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/node": {
+      "version": "7.17.10",
+      "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.17.10.tgz",
+      "integrity": "sha512-sFFMyvw23U8QOcTnLJnw2/Myr01e4+iLVy7rHAHrNSnXAfnwS3j2NqihpmZm7TotyNKKf/y8cJ96T5asY46eyw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/register": "^7.17.7",
+        "commander": "^4.0.1",
+        "core-js": "^3.22.1",
+        "node-environment-flags": "^1.0.5",
+        "regenerator-runtime": "^0.13.4",
+        "v8flags": "^3.1.1"
+      },
+      "bin": {
+        "babel-node": "bin/babel-node.js"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
     "node_modules/@babel/parser": {
       "version": "7.16.8",
       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.8.tgz",
@@ -1755,6 +1779,121 @@
         "@babel/core": "^7.0.0-0"
       }
     },
+    "node_modules/@babel/register": {
+      "version": "7.17.7",
+      "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.17.7.tgz",
+      "integrity": "sha512-fg56SwvXRifootQEDQAu1mKdjh5uthPzdO0N6t358FktfL4XjAVXuH58ULoiW8mesxiOgNIrxiImqEwv0+hRRA==",
+      "dev": true,
+      "dependencies": {
+        "clone-deep": "^4.0.1",
+        "find-cache-dir": "^2.0.0",
+        "make-dir": "^2.1.0",
+        "pirates": "^4.0.5",
+        "source-map-support": "^0.5.16"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/register/node_modules/find-cache-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+      "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+      "dev": true,
+      "dependencies": {
+        "commondir": "^1.0.1",
+        "make-dir": "^2.0.0",
+        "pkg-dir": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@babel/register/node_modules/find-up": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@babel/register/node_modules/locate-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@babel/register/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@babel/register/node_modules/p-locate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@babel/register/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@babel/register/node_modules/path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@babel/register/node_modules/pkg-dir": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+      "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+      "dev": true,
+      "dependencies": {
+        "find-up": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/@babel/runtime": {
       "version": "7.16.7",
       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz",
@@ -6029,6 +6168,15 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/commander": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+      "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/comment-parser": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.0.tgz",
@@ -6177,9 +6325,9 @@
       }
     },
     "node_modules/core-js": {
-      "version": "3.22.0",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.0.tgz",
-      "integrity": "sha512-8h9jBweRjMiY+ORO7bdWSeWfHhLPO7whobj7Z2Bl0IDo00C228EdGgH7FE4jGumbEjzcFfkfW8bXgdkEDhnwHQ==",
+      "version": "3.22.5",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.5.tgz",
+      "integrity": "sha512-VP/xYuvJ0MJWRAobcmQ8F2H6Bsn+s7zqAAjFaHGBMc5AQm7zaelhD1LGduFn2EehEcQcU+br6t+fwbpQ5d1ZWA==",
       "hasInstallScript": true,
       "funding": {
         "type": "opencollective",
@@ -7048,7 +7196,6 @@
       "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz",
       "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "call-bind": "^1.0.2",
         "es-to-primitive": "^1.2.1",
@@ -7088,7 +7235,6 @@
       "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
       "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "is-callable": "^1.1.4",
         "is-date-object": "^1.0.1",
@@ -9003,7 +9149,6 @@
       "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
       "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "call-bind": "^1.0.2",
         "get-intrinsic": "^1.1.1"
@@ -9374,7 +9519,6 @@
       "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
       "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
       "dev": true,
-      "peer": true,
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -9405,7 +9549,6 @@
       "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
       "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "has-symbols": "^1.0.2"
       },
@@ -9499,6 +9642,18 @@
         "he": "bin/he"
       }
     },
+    "node_modules/homedir-polyfill": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+      "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+      "dev": true,
+      "dependencies": {
+        "parse-passwd": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/hosted-git-info": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@@ -9848,7 +10003,6 @@
       "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
       "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "get-intrinsic": "^1.1.0",
         "has": "^1.0.3",
@@ -9904,7 +10058,6 @@
       "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
       "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "has-bigints": "^1.0.1"
       },
@@ -9929,7 +10082,6 @@
       "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
       "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "call-bind": "^1.0.2",
         "has-tostringtag": "^1.0.0"
@@ -9951,7 +10103,6 @@
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
       "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">= 0.4"
       },
@@ -10000,7 +10151,6 @@
       "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
       "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "has-tostringtag": "^1.0.0"
       },
@@ -10099,7 +10249,6 @@
       "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
       "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">= 0.4"
       },
@@ -10121,7 +10270,6 @@
       "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
       "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "has-tostringtag": "^1.0.0"
       },
@@ -10162,7 +10310,6 @@
       "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
       "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "call-bind": "^1.0.2",
         "has-tostringtag": "^1.0.0"
@@ -10189,7 +10336,6 @@
       "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
       "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==",
       "dev": true,
-      "peer": true,
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -10211,7 +10357,6 @@
       "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
       "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "has-tostringtag": "^1.0.0"
       },
@@ -10227,7 +10372,6 @@
       "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
       "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "has-symbols": "^1.0.2"
       },
@@ -10249,7 +10393,6 @@
       "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
       "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "call-bind": "^1.0.2"
       },
@@ -13313,6 +13456,28 @@
         "lz-string": "bin/bin.js"
       }
     },
+    "node_modules/make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "dev": true,
+      "dependencies": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/make-dir/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
     "node_modules/make-fetch-happen": {
       "version": "9.1.0",
       "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
@@ -14135,6 +14300,25 @@
         "@sinonjs/commons": "^1.7.0"
       }
     },
+    "node_modules/node-environment-flags": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+      "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+      "dev": true,
+      "dependencies": {
+        "object.getownpropertydescriptors": "^2.0.3",
+        "semver": "^5.7.0"
+      }
+    },
+    "node_modules/node-environment-flags/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
     "node_modules/node-fetch": {
       "version": "2.6.7",
       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
@@ -14599,7 +14783,6 @@
       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
       "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
       "dev": true,
-      "peer": true,
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -14643,6 +14826,23 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/object.getownpropertydescriptors": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz",
+      "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.19.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/object.pick": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
@@ -14877,6 +15077,15 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/parse-passwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/parse5": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@@ -15001,10 +15210,19 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
+    "node_modules/pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/pirates": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz",
-      "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
+      "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
       "dev": true,
       "engines": {
         "node": ">= 6"
@@ -16776,7 +16994,6 @@
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
       "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "call-bind": "^1.0.0",
         "get-intrinsic": "^1.0.2",
@@ -17580,7 +17797,6 @@
       "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
       "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "call-bind": "^1.0.2",
         "define-properties": "^1.1.3"
@@ -17594,7 +17810,6 @@
       "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
       "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "call-bind": "^1.0.2",
         "define-properties": "^1.1.3"
@@ -18541,7 +18756,6 @@
       "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
       "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "function-bind": "^1.1.1",
         "has-bigints": "^1.0.1",
@@ -18861,6 +19075,18 @@
         "node": ">= 8"
       }
     },
+    "node_modules/v8flags": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
+      "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
+      "dev": true,
+      "dependencies": {
+        "homedir-polyfill": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
     "node_modules/validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -19553,7 +19779,6 @@
       "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
       "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "is-bigint": "^1.0.1",
         "is-boolean-object": "^1.1.0",
@@ -20134,6 +20359,20 @@
         "js-tokens": "^4.0.0"
       }
     },
+    "@babel/node": {
+      "version": "7.17.10",
+      "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.17.10.tgz",
+      "integrity": "sha512-sFFMyvw23U8QOcTnLJnw2/Myr01e4+iLVy7rHAHrNSnXAfnwS3j2NqihpmZm7TotyNKKf/y8cJ96T5asY46eyw==",
+      "dev": true,
+      "requires": {
+        "@babel/register": "^7.17.7",
+        "commander": "^4.0.1",
+        "core-js": "^3.22.1",
+        "node-environment-flags": "^1.0.5",
+        "regenerator-runtime": "^0.13.4",
+        "v8flags": "^3.1.1"
+      }
+    },
     "@babel/parser": {
       "version": "7.16.8",
       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.8.tgz",
@@ -20946,6 +21185,90 @@
         "esutils": "^2.0.2"
       }
     },
+    "@babel/register": {
+      "version": "7.17.7",
+      "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.17.7.tgz",
+      "integrity": "sha512-fg56SwvXRifootQEDQAu1mKdjh5uthPzdO0N6t358FktfL4XjAVXuH58ULoiW8mesxiOgNIrxiImqEwv0+hRRA==",
+      "dev": true,
+      "requires": {
+        "clone-deep": "^4.0.1",
+        "find-cache-dir": "^2.0.0",
+        "make-dir": "^2.1.0",
+        "pirates": "^4.0.5",
+        "source-map-support": "^0.5.16"
+      },
+      "dependencies": {
+        "find-cache-dir": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+          "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^2.0.0",
+            "pkg-dir": "^3.0.0"
+          }
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+          "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+          "dev": true,
+          "requires": {
+            "find-up": "^3.0.0"
+          }
+        }
+      }
+    },
     "@babel/runtime": {
       "version": "7.16.7",
       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz",
@@ -24360,6 +24683,12 @@
         "delayed-stream": "~1.0.0"
       }
     },
+    "commander": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+      "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+      "dev": true
+    },
     "comment-parser": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.0.tgz",
@@ -24488,9 +24817,9 @@
       "dev": true
     },
     "core-js": {
-      "version": "3.22.0",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.0.tgz",
-      "integrity": "sha512-8h9jBweRjMiY+ORO7bdWSeWfHhLPO7whobj7Z2Bl0IDo00C228EdGgH7FE4jGumbEjzcFfkfW8bXgdkEDhnwHQ=="
+      "version": "3.22.5",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.5.tgz",
+      "integrity": "sha512-VP/xYuvJ0MJWRAobcmQ8F2H6Bsn+s7zqAAjFaHGBMc5AQm7zaelhD1LGduFn2EehEcQcU+br6t+fwbpQ5d1ZWA=="
     },
     "core-js-compat": {
       "version": "3.20.3",
@@ -25180,7 +25509,6 @@
       "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz",
       "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==",
       "dev": true,
-      "peer": true,
       "requires": {
         "call-bind": "^1.0.2",
         "es-to-primitive": "^1.2.1",
@@ -25214,7 +25542,6 @@
       "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
       "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
       "dev": true,
-      "peer": true,
       "requires": {
         "is-callable": "^1.1.4",
         "is-date-object": "^1.0.1",
@@ -26642,7 +26969,6 @@
       "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
       "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
       "dev": true,
-      "peer": true,
       "requires": {
         "call-bind": "^1.0.2",
         "get-intrinsic": "^1.1.1"
@@ -26928,8 +27254,7 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
       "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "has-flag": {
       "version": "3.0.0",
@@ -26948,7 +27273,6 @@
       "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
       "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
       "dev": true,
-      "peer": true,
       "requires": {
         "has-symbols": "^1.0.2"
       }
@@ -27022,6 +27346,15 @@
       "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
       "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
     },
+    "homedir-polyfill": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+      "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+      "dev": true,
+      "requires": {
+        "parse-passwd": "^1.0.0"
+      }
+    },
     "hosted-git-info": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@@ -27282,7 +27615,6 @@
       "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
       "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
       "dev": true,
-      "peer": true,
       "requires": {
         "get-intrinsic": "^1.1.0",
         "has": "^1.0.3",
@@ -27329,7 +27661,6 @@
       "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
       "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "has-bigints": "^1.0.1"
       }
@@ -27348,7 +27679,6 @@
       "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
       "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
       "dev": true,
-      "peer": true,
       "requires": {
         "call-bind": "^1.0.2",
         "has-tostringtag": "^1.0.0"
@@ -27363,8 +27693,7 @@
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
       "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "is-ci": {
       "version": "2.0.0",
@@ -27398,7 +27727,6 @@
       "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
       "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
       "dev": true,
-      "peer": true,
       "requires": {
         "has-tostringtag": "^1.0.0"
       }
@@ -27463,8 +27791,7 @@
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
       "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "is-number": {
       "version": "7.0.0",
@@ -27477,7 +27804,6 @@
       "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
       "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
       "dev": true,
-      "peer": true,
       "requires": {
         "has-tostringtag": "^1.0.0"
       }
@@ -27506,7 +27832,6 @@
       "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
       "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "call-bind": "^1.0.2",
         "has-tostringtag": "^1.0.0"
@@ -27523,8 +27848,7 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
       "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "is-stream": {
       "version": "2.0.1",
@@ -27537,7 +27861,6 @@
       "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
       "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "has-tostringtag": "^1.0.0"
       }
@@ -27547,7 +27870,6 @@
       "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
       "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "has-symbols": "^1.0.2"
       }
@@ -27563,7 +27885,6 @@
       "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
       "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
       "dev": true,
-      "peer": true,
       "requires": {
         "call-bind": "^1.0.2"
       }
@@ -29911,6 +30232,24 @@
       "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=",
       "dev": true
     },
+    "make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "dev": true,
+      "requires": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        }
+      }
+    },
     "make-fetch-happen": {
       "version": "9.1.0",
       "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
@@ -30553,6 +30892,24 @@
         }
       }
     },
+    "node-environment-flags": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+      "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+      "dev": true,
+      "requires": {
+        "object.getownpropertydescriptors": "^2.0.3",
+        "semver": "^5.7.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        }
+      }
+    },
     "node-fetch": {
       "version": "2.6.7",
       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
@@ -30919,8 +31276,7 @@
       "version": "1.12.0",
       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
       "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "object-keys": {
       "version": "1.1.1",
@@ -30949,6 +31305,17 @@
         "object-keys": "^1.1.1"
       }
     },
+    "object.getownpropertydescriptors": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz",
+      "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.19.1"
+      }
+    },
     "object.pick": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
@@ -31107,6 +31474,12 @@
         "lines-and-columns": "^1.1.6"
       }
     },
+    "parse-passwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+      "dev": true
+    },
     "parse5": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@@ -31209,10 +31582,16 @@
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
       "dev": true
     },
+    "pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true
+    },
     "pirates": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz",
-      "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
+      "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
       "dev": true
     },
     "pkg-dir": {
@@ -32546,7 +32925,6 @@
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
       "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
       "dev": true,
-      "peer": true,
       "requires": {
         "call-bind": "^1.0.0",
         "get-intrinsic": "^1.0.2",
@@ -33203,7 +33581,6 @@
       "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
       "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
       "dev": true,
-      "peer": true,
       "requires": {
         "call-bind": "^1.0.2",
         "define-properties": "^1.1.3"
@@ -33214,7 +33591,6 @@
       "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
       "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
       "dev": true,
-      "peer": true,
       "requires": {
         "call-bind": "^1.0.2",
         "define-properties": "^1.1.3"
@@ -33926,7 +34302,6 @@
       "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
       "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
       "dev": true,
-      "peer": true,
       "requires": {
         "function-bind": "^1.1.1",
         "has-bigints": "^1.0.1",
@@ -34187,6 +34562,15 @@
         }
       }
     },
+    "v8flags": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
+      "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "^1.0.1"
+      }
+    },
     "validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -34703,7 +35087,6 @@
       "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
       "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "is-bigint": "^1.0.1",
         "is-boolean-object": "^1.1.0",

+ 3 - 1
package.json

@@ -15,7 +15,8 @@
     "lint:fix": "eslint '**/src/**/*.{vue,js}' --fix",
     "test": "jest",
     "test:watch": "jest --watch",
-    "test:jsunit": "karma start tests/karma.config.js --single-run"
+    "test:jsunit": "karma start tests/karma.config.js --single-run",
+    "sass:icons": "babel-node core/src/icons.js"
   },
   "repository": {
     "type": "git",
@@ -97,6 +98,7 @@
     "webdav": "^4.8.0"
   },
   "devDependencies": {
+    "@babel/node": "^7.17.10",
     "@nextcloud/babel-config": "^1.0.0",
     "@nextcloud/browserslist-config": "^2.2.0",
     "@nextcloud/eslint-config": "^7.0.2",

Some files were not shown because too many files changed in this diff