diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx index cc6eb72ca..a8ee10562 100644 --- a/client/admin/admin.jsx +++ b/client/admin/admin.jsx @@ -49,4 +49,4 @@ const Admin = ()=>{ ); }; -module.exports = Admin; +export default Admin; diff --git a/client/admin/admin.less b/client/admin/admin.less index 0fc353194..432f92e8b 100644 --- a/client/admin/admin.less +++ b/client/admin/admin.less @@ -1,11 +1,9 @@ -@import 'naturalcrit/styles/reset.less'; -@import 'naturalcrit/styles/elements.less'; -@import 'naturalcrit/styles/animations.less'; -@import 'naturalcrit/styles/colors.less'; -@import 'naturalcrit/styles/tooltip.less'; -@import './themes/fonts/iconFonts/fontAwesome.less'; - -@import 'font-awesome/css/font-awesome.css'; +@import '@sharedStyles/reset.less'; +@import '@sharedStyles/elements.less'; +@import '@sharedStyles/animations.less'; +@import '@sharedStyles/colors.less'; +@import '@sharedStyles/tooltip.less'; +@import '@themes/fonts/iconFonts/fontAwesome.less'; html,body, #reactContainer, .naturalCrit { min-height : 100%; } diff --git a/client/admin/brewUtils/brewUtils.less b/client/admin/brewUtils/brewUtils.less index 5bbbc3f69..cfa7dbbdf 100644 --- a/client/admin/brewUtils/brewUtils.less +++ b/client/admin/brewUtils/brewUtils.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/colors.less'; + .brewUtil { .result { margin-top : 20px; diff --git a/client/admin/main.jsx b/client/admin/main.jsx new file mode 100644 index 000000000..a5b7c84ad --- /dev/null +++ b/client/admin/main.jsx @@ -0,0 +1,6 @@ +import { createRoot } from 'react-dom/client'; +import Admin from './admin.jsx'; + +const props = window.__INITIAL_PROPS__ || {}; + +createRoot(document.getElementById('reactRoot')).render(); diff --git a/client/components/codeEditor/autocompleteEmoji.js b/client/components/codeEditor/autocompleteEmoji.js index d5a3a71aa..fc64e7bbd 100644 --- a/client/components/codeEditor/autocompleteEmoji.js +++ b/client/components/codeEditor/autocompleteEmoji.js @@ -1,7 +1,7 @@ -import diceFont from 'themes/fonts/iconFonts/diceFont.js'; -import elderberryInn from 'themes/fonts/iconFonts/elderberryInn.js'; -import fontAwesome from 'themes/fonts/iconFonts/fontAwesome.js'; -import gameIcons from 'themes/fonts/iconFonts/gameIcons.js'; +import diceFont from '@themes/fonts/iconFonts/diceFont.js'; +import elderberryInn from '@themes/fonts/iconFonts/elderberryInn.js'; +import fontAwesome from '@themes/fonts/iconFonts/fontAwesome.js'; +import gameIcons from '@themes/fonts/iconFonts/gameIcons.js'; const emojis = { ...diceFont, diff --git a/client/components/codeEditor/codeEditor.jsx b/client/components/codeEditor/codeEditor.jsx index 3ec986689..cd140ad07 100644 --- a/client/components/codeEditor/codeEditor.jsx +++ b/client/components/codeEditor/codeEditor.jsx @@ -12,6 +12,7 @@ const CodeEditor = createReactClass({ getDefaultProps : function() { return { language : '', + tab : 'brewText', value : '', wrap : true, onChange : ()=>{}, @@ -186,6 +187,22 @@ const CodeEditor = createReactClass({ this.updateSize(); }, + // Use for GFM tabs that use common hot-keys + isGFM : function() { + if((this.isGFM()) || (this.props.tab === 'brewSnippets')) return true; + return false; + }, + + isBrewText : function() { + if(this.isGFM()) return true; + return false; + }, + + isBrewSnippets : function() { + if(this.props.tab === 'brewSnippets') return true; + return false; + }, + indent : function () { const cm = this.codeMirror; if(cm.somethingSelected()) { @@ -200,6 +217,7 @@ const CodeEditor = createReactClass({ }, makeHeader : function (number) { + if(!this.isGFM()) return; const selection = this.codeMirror?.getSelection(); const header = Array(number).fill('#').join(''); this.codeMirror?.replaceSelection(`${header} ${selection}`, 'around'); @@ -208,6 +226,7 @@ const CodeEditor = createReactClass({ }, makeBold : function() { + if(!this.isGFM()) return; const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 2) === '**' && selection.slice(-2) === '**'; this.codeMirror?.replaceSelection(t ? selection.slice(2, -2) : `**${selection}**`, 'around'); if(selection.length === 0){ @@ -217,7 +236,8 @@ const CodeEditor = createReactClass({ }, makeItalic : function() { - const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 1) === '*' && selection.slice(-1) === '*'; + if(!this.isGFM()) return; + const selection = this.codeMirror.getSelection(), t = selection.slice(0, 1) === '*' && selection.slice(-1) === '*'; this.codeMirror?.replaceSelection(t ? selection.slice(1, -1) : `*${selection}*`, 'around'); if(selection.length === 0){ const cursor = this.codeMirror?.getCursor(); @@ -226,7 +246,8 @@ const CodeEditor = createReactClass({ }, makeSuper : function() { - const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 1) === '^' && selection.slice(-1) === '^'; + if(!this.isGFM()) return; + const selection = this.codeMirror.getSelection(), t = selection.slice(0, 1) === '^' && selection.slice(-1) === '^'; this.codeMirror?.replaceSelection(t ? selection.slice(1, -1) : `^${selection}^`, 'around'); if(selection.length === 0){ const cursor = this.codeMirror?.getCursor(); @@ -235,7 +256,8 @@ const CodeEditor = createReactClass({ }, makeSub : function() { - const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 2) === '^^' && selection.slice(-2) === '^^'; + if(!this.isGFM()) return; + const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '^^' && selection.slice(-2) === '^^'; this.codeMirror?.replaceSelection(t ? selection.slice(2, -2) : `^^${selection}^^`, 'around'); if(selection.length === 0){ const cursor = this.codeMirror?.getCursor(); @@ -245,10 +267,12 @@ const CodeEditor = createReactClass({ makeNbsp : function() { + if(!this.isGFM()) return; this.codeMirror?.replaceSelection(' ', 'end'); }, makeSpace : function() { + if(!this.isGFM()) return; const selection = this.codeMirror?.getSelection(); const t = selection.slice(0, 8) === '{{width:' && selection.slice(0 -4) === '% }}'; if(t){ @@ -260,6 +284,7 @@ const CodeEditor = createReactClass({ }, removeSpace : function() { + if(!this.isGFM()) return; const selection = this.codeMirror?.getSelection(); const t = selection.slice(0, 8) === '{{width:' && selection.slice(0 -4) === '% }}'; if(t){ @@ -269,10 +294,12 @@ const CodeEditor = createReactClass({ }, newColumn : function() { + if(!this.isGFM()) return; this.codeMirror?.replaceSelection('\n\\column\n\n', 'end'); }, newPage : function() { + if(!this.isGFM()) return; this.codeMirror?.replaceSelection('\n\\page\n\n', 'end'); }, @@ -286,7 +313,8 @@ const CodeEditor = createReactClass({ }, makeUnderline : function() { - const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 3) === '' && selection.slice(-4) === ''; + if(!this.isGFM()) return; + const selection = this.codeMirror.getSelection(), t = selection.slice(0, 3) === '' && selection.slice(-4) === ''; this.codeMirror?.replaceSelection(t ? selection.slice(3, -4) : `${selection}`, 'around'); if(selection.length === 0){ const cursor = this.codeMirror?.getCursor(); @@ -295,7 +323,8 @@ const CodeEditor = createReactClass({ }, makeSpan : function() { - const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}'; + if(!this.isGFM()) return; + const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}'; this.codeMirror?.replaceSelection(t ? selection.slice(2, -2) : `{{ ${selection}}}`, 'around'); if(selection.length === 0){ const cursor = this.codeMirror?.getCursor(); @@ -304,7 +333,8 @@ const CodeEditor = createReactClass({ }, makeDiv : function() { - const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}'; + if(!this.isGFM()) return; + const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}'; this.codeMirror?.replaceSelection(t ? selection.slice(2, -2) : `{{\n${selection}\n}}`, 'around'); if(selection.length === 0){ const cursor = this.codeMirror?.getCursor(); @@ -317,7 +347,7 @@ const CodeEditor = createReactClass({ let cursorPos; let newComment; const selection = this.codeMirror?.getSelection(); - if(this.props.language === 'gfm'){ + if(this.isGFM()){ regex = /^\s*()\s*$/gs; cursorPos = 4; newComment = ``; @@ -334,6 +364,7 @@ const CodeEditor = createReactClass({ }, makeLink : function() { + if(!this.isGFM()) return; const isLink = /^\[(.*)\]\((.*)\)$/; const selection = this.codeMirror?.getSelection().trim(); let match; @@ -351,7 +382,8 @@ const CodeEditor = createReactClass({ }, makeList : function(listType) { - const selectionStart = this.codeMirror?.getCursor('from'), selectionEnd = this.codeMirror?.getCursor('to'); + if(!this.isGFM()) return; + const selectionStart = this.codeMirror.getCursor('from'), selectionEnd = this.codeMirror.getCursor('to'); this.codeMirror?.setSelection( { line: selectionStart.line, ch: 0 }, { line: selectionEnd.line, ch: this.codeMirror?.getLine(selectionEnd.line).length } diff --git a/client/components/codeEditor/codeEditor.less b/client/components/codeEditor/codeEditor.less index c8e60974b..89d0c9497 100644 --- a/client/components/codeEditor/codeEditor.less +++ b/client/components/codeEditor/codeEditor.less @@ -5,10 +5,10 @@ @import (less) 'codemirror/addon/hint/show-hint.css'; //Icon fonts included so they can appear in emoji autosuggest dropdown -@import (less) './themes/fonts/iconFonts/diceFont.less'; -@import (less) './themes/fonts/iconFonts/elderberryInn.less'; -@import (less) './themes/fonts/iconFonts/gameIcons.less'; -@import (less) './themes/fonts/iconFonts/fontAwesome.less'; +@import (less) '@themes/fonts/iconFonts/diceFont.less'; +@import (less) '@themes/fonts/iconFonts/elderberryInn.less'; +@import (less) '@themes/fonts/iconFonts/gameIcons.less'; +@import (less) '@themes/fonts/iconFonts/fontAwesome.less'; @keyframes sourceMoveAnimation { 50% { color : white;background-color : red;} diff --git a/client/components/combobox.jsx b/client/components/combobox.jsx index 651a31516..7c015d3d6 100644 --- a/client/components/combobox.jsx +++ b/client/components/combobox.jsx @@ -11,14 +11,17 @@ const Combobox = createReactClass({ trigger : 'hover', default : '', placeholder : '', + tooltip : '', autoSuggest : { clearAutoSuggestOnClick : true, suggestMethod : 'includes', filterOn : [] // should allow as array to filter on multiple attributes, or even custom filter }, + valuePatterns : /.+/ }; }, getInitialState : function() { + this.dropdownRef = React.createRef(); return { showDropdown : false, value : '', @@ -39,7 +42,7 @@ const Combobox = createReactClass({ }, handleClickOutside : function(e){ // Close dropdown when clicked outside - if(this.refs.dropdown && !this.refs.dropdown.contains(e.target)) { + if(this.dropdownRef.current && !this.dropdownRef.current.contains(e.target)) { this.handleDropdown(false); } }, @@ -69,11 +72,14 @@ const Combobox = createReactClass({ return (
{this.handleDropdown(true);} : undefined} - onClick= {this.props.trigger == 'click' ? ()=>{this.handleDropdown(true);} : undefined}> + onClick= {this.props.trigger == 'click' ? ()=>{this.handleDropdown(true);} : undefined} + {...(this.props.tooltip ? { 'data-tooltip-right': this.props.tooltip } : {})}> this.handleInput(e)} value={this.state.value || ''} + title='' + pattern={this.props.valuePatterns} placeholder={this.props.placeholder} onBlur={(e)=>{ if(!e.target.checkValidity()){ @@ -82,6 +88,12 @@ const Combobox = createReactClass({ }); } }} + onKeyDown={(e)=>{ + if(e.key === 'Enter') { + e.preventDefault(); + this.props.onEntry(e); + } + }} />
@@ -117,7 +129,7 @@ const Combobox = createReactClass({ }); return (
{this.handleDropdown(false);} : undefined}> {this.renderTextInput()} {this.renderDropdown(dropdownChildren)} diff --git a/client/components/combobox.less b/client/components/combobox.less index 27f78356b..a3c7527f2 100644 --- a/client/components/combobox.less +++ b/client/components/combobox.less @@ -10,6 +10,7 @@ position : absolute; z-index : 100; width : 100%; + height : max-content; max-height : 200px; overflow-y : auto; background-color : white; diff --git a/client/components/renderWarnings/renderWarnings.less b/client/components/renderWarnings/renderWarnings.less index 70799092a..a1413709b 100644 --- a/client/components/renderWarnings/renderWarnings.less +++ b/client/components/renderWarnings/renderWarnings.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/colors.less'; + .renderWarnings { position : relative; float : right; diff --git a/client/components/splitPane/splitPane.less b/client/components/splitPane/splitPane.less index 80a8695af..779d0c222 100644 --- a/client/components/splitPane/splitPane.less +++ b/client/components/splitPane/splitPane.less @@ -1,3 +1,4 @@ +@import '@sharedStyles/core.less'; .splitPane { position : relative; diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 771a6aa31..8e74473b3 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -1,10 +1,12 @@ /*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/ +import brewRendererStylesUrl from './brewRenderer.less?url'; +import headerNavStylesUrl from './headerNav/headerNav.less?url'; import './brewRenderer.less'; import React, { useState, useRef, useMemo, useEffect } from 'react'; import _ from 'lodash'; -import MarkdownLegacy from '../../../shared/markdownLegacy.js'; -import Markdown from '../../../shared/markdown.js'; +import MarkdownLegacy from '@shared/markdownLegacy.js'; +import Markdown from '@shared/markdown.js'; import ErrorBar from './errorBar/errorBar.jsx'; import ToolBar from './toolBar/toolBar.jsx'; @@ -13,10 +15,10 @@ import RenderWarnings from '../../components/renderWarnings/renderWarnings.jsx'; import NotificationPopup from './notificationPopup/notificationPopup.jsx'; import Frame from 'react-frame-component'; import dedent from 'dedent'; -import { printCurrentBrew } from '../../../shared/helpers.js'; +import { printCurrentBrew } from '@shared/helpers.js'; import HeaderNav from './headerNav/headerNav.jsx'; -import { safeHTML } from './safeHTML.js'; +import safeHTML from './safeHTML.js'; const PAGEBREAK_REGEX_V3 = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m; const PAGEBREAK_REGEX_LEGACY = /\\page(?:break)?/m; @@ -29,6 +31,8 @@ const INITIAL_CONTENT = dedent` + +
`; diff --git a/client/homebrew/brewRenderer/brewRenderer.less b/client/homebrew/brewRenderer/brewRenderer.less index 5769a13df..ea9b43d75 100644 --- a/client/homebrew/brewRenderer/brewRenderer.less +++ b/client/homebrew/brewRenderer/brewRenderer.less @@ -1,4 +1,4 @@ -@import (multiple, less) 'shared/naturalcrit/styles/reset.less'; +@import '@sharedStyles/core.less'; .brewRenderer { height : 100vh; diff --git a/client/homebrew/brewRenderer/errorBar/errorBar.less b/client/homebrew/brewRenderer/errorBar/errorBar.less index 163648533..528521a07 100644 --- a/client/homebrew/brewRenderer/errorBar/errorBar.less +++ b/client/homebrew/brewRenderer/errorBar/errorBar.less @@ -1,3 +1,4 @@ +@import '@sharedStyles/colors.less'; .errorBar { position : absolute; diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx index dd05391f0..5f4fc5608 100644 --- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx +++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx @@ -1,7 +1,7 @@ import './notificationPopup.less'; import React, { useEffect, useState } from 'react'; import request from '../../utils/request-middleware.js'; -import Markdown from 'markdown.js'; +import Markdown from '@shared/markdown.js'; import Dialog from '../../../components/dialog.jsx'; diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less index 85d4c8365..4f34bad8d 100644 --- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less +++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less @@ -1,3 +1,5 @@ +@import './client/homebrew/navbar/navbar.less'; + .popups { position : fixed; top : calc(@navbarHeight + @viewerToolsHeight); diff --git a/client/homebrew/brewRenderer/safeHTML.js b/client/homebrew/brewRenderer/safeHTML.js index 2574f4cfe..d9438b663 100644 --- a/client/homebrew/brewRenderer/safeHTML.js +++ b/client/homebrew/brewRenderer/safeHTML.js @@ -43,4 +43,4 @@ function safeHTML(htmlString) { return div.innerHTML; }; -module.exports.safeHTML = safeHTML; \ No newline at end of file +export default safeHTML; \ No newline at end of file diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index be0842f33..97d996633 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -99,18 +99,18 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa return (
; } else { dropdown = -
+
- Select from the list below (built-in themes and brews you have tagged "meta:theme"), or paste in the Share URL or Share ID of any brew.
; } @@ -280,7 +256,7 @@ const MetadataEditor = createReactClass({ return
-
+
- Sets the HTML Lang property for your brew. May affect hyphenation or spellcheck.
; }, renderRenderOptions : function(){ - return
+ return
- this.handleFieldChange('tags', e)} - /> - -
- -
- {this.renderSystems()} +
+ +
+ this.handleFieldChange('tags', e)} + tooltip='You may start tags with "type", "system", "group" or "meta" followed by a colon ":", these will be colored in your userpage.' + />
+ {this.renderLanguageDropdown()} {this.renderThemeDropdown()} @@ -386,13 +363,22 @@ const MetadataEditor = createReactClass({ {this.renderAuthors()} - !this.props.metadata.authors?.includes(v)]} - placeholder='invite author' unique={true} - values={this.props.metadata.invitedAuthors} - notes={['Invited author usernames are case sensitive.', 'After adding an invited author, send them the edit link. There, they can choose to accept or decline the invitation.']} - onChange={(e)=>this.handleFieldChange('invitedAuthors', e)} - /> +
+ +
+ !this.props.metadata.authors?.includes(v)]} + placeholder='invite author' unique={true} + tooltip={`Invited author usernames are case sensitive. + After adding an invited author, send them the edit link. There, they can choose to accept or decline the invitation.`} + values={this.props.metadata.invitedAuthors} + onChange={(e)=>this.handleFieldChange('invitedAuthors', e)} + /> +
+
+

Privacy

diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index fd04f07d9..6a4df1c46 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -1,4 +1,4 @@ -@import 'naturalcrit/styles/colors.less'; +@import '@sharedStyles/core.less'; .userThemeName { padding-right : 10px; @@ -44,8 +44,6 @@ gap : 10px; } - - .field { position : relative; display : flex; @@ -62,6 +60,7 @@ & > .value { flex : 1 1 auto; width : 50px; + &[data-tooltip-right] { max-width : 380px; } &:invalid { background : #FFB9B9; } small { display : block; @@ -74,6 +73,16 @@ border : 1px solid gray; &:focus { outline : 1px solid #444444; } } + + &.description { + flex : 1; + textarea.value { + height : auto; + font-family : 'Open Sans', sans-serif; + resize : none; + } + } + &.thumbnail, &.themes { label { line-height : 2.0em; } .value { @@ -90,6 +99,15 @@ } } + &.tags .tagInput-dropdown { + z-index : 400; + max-width : 200px; + } + &.language .value { + z-index : 300; + max-width : 150px; + } + &.themes { .value { overflow : visible; @@ -101,22 +119,13 @@ } } - &.description { - flex : 1; - textarea.value { - height : auto; - font-family : 'Open Sans', sans-serif; - resize : none; - } - } - - &.language .language-dropdown { - z-index : 200; - max-width : 150px; + &.invitedAuthors .value { + z-index : 100; + + .tagInput-dropdown { max-width : 200px; } } } - .thumbnail-preview { position : relative; flex : 1 1; @@ -129,7 +138,7 @@ background-color : #AAAAAA; } - .systems.field .value { + .renderers.field .value { label { display : inline-flex; align-items : center; @@ -169,7 +178,7 @@ .themes.field { & .dropdown-container { position : relative; - z-index : 100; + z-index : 200; background-color : white; } & .dropdown-options { overflow-y : visible; } diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index b6e977ea2..304664ff5 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -7,13 +7,13 @@ import _ from 'lodash'; import cx from 'classnames'; import { loadHistory } from '../../utils/versionHistory.js'; -import { brewSnippetsToJSON } from '../../../../shared/helpers.js'; +import { brewSnippetsToJSON } from '@shared/helpers.js'; -import Legacy5ePHB from 'themes/Legacy/5ePHB/snippets.js'; -import V3_5ePHB from 'themes/V3/5ePHB/snippets.js'; -import V3_5eDMG from 'themes/V3/5eDMG/snippets.js'; -import V3_Journal from 'themes/V3/Journal/snippets.js'; -import V3_Blank from 'themes/V3/Blank/snippets.js'; +import Legacy5ePHB from '@themes/Legacy/5ePHB/snippets.js'; +import V3_5ePHB from '@themes/V3/5ePHB/snippets.js'; +import V3_5eDMG from '@themes/V3/5eDMG/snippets.js'; +import V3_Journal from '@themes/V3/Journal/snippets.js'; +import V3_Blank from '@themes/V3/Blank/snippets.js'; const ThemeSnippets = { Legacy_5ePHB : Legacy5ePHB, @@ -23,7 +23,7 @@ const ThemeSnippets = { V3_Blank : V3_Blank, }; -import EditorThemes from 'build/homebrew/codeMirror/editorThemes.json'; +import EditorThemes from '../../../../build/homebrew/codeMirror/editorThemes.json'; const execute = function(val, props){ if(_.isFunction(val)) return val(props); diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 8e50aa764..37853ca75 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -1,5 +1,6 @@ +@import '@sharedStyles/core.less'; @import (less) './client/icons/customIcons.less'; -@import (less) '././././themes/fonts/5e/fonts.less'; +@import (less) '@themes/fonts/5e/fonts.less'; .snippetBar { @menuHeight : 25px; diff --git a/client/homebrew/editor/tagInput/curatedTagSuggestionList.js b/client/homebrew/editor/tagInput/curatedTagSuggestionList.js new file mode 100644 index 000000000..9b9afce6f --- /dev/null +++ b/client/homebrew/editor/tagInput/curatedTagSuggestionList.js @@ -0,0 +1,210 @@ +export default [ + // ############################## Systems + // D&D + 'system:D&D Original', + 'system:D&D Basic', + 'system:AD&D 1e', + 'system:AD&D 2e', + 'system:D&D 3e', + 'system:D&D 3.5e', + 'system:D&D 4e', + 'system:D&D 5e', + 'system:D&D 5e 2024', + 'system:BD&D (B/X)', + 'system:D&D Essentials', + + // Other Famous RPGs + 'system:Pathfinder 1e', + 'system:Pathfinder 2e', + 'system:Vampire: The Masquerade', + 'system:Werewolf: The Apocalypse', + 'system:Mage: The Ascension', + 'system:Call of Cthulhu', + 'system:Shadowrun', + 'system:Star Wars RPG (D6/D20/Edge of the Empire)', + 'system:Warhammer Fantasy Roleplay', + 'system:Cyberpunk 2020', + 'system:Blades in the Dark', + 'system:Daggerheart', + 'system:Draw Steel', + 'system:Mutants and Masterminds', + + // Meta + 'meta:V3', + 'meta:Legacy', + 'meta:Template', + 'meta:Theme', + 'meta:free', + 'meta:Character Sheet', + 'meta:Documentation', + 'meta:NPC', + 'meta:Guide', + 'meta:Resource', + 'meta:Notes', + 'meta:Example', + + // Book type + 'type:Campaign', + 'type:Campaign Setting', + 'type:Adventure', + 'type:One-Shot', + 'type:Setting', + 'type:World', + 'type:Lore', + 'type:History', + 'type:Dungeon Master', + 'type:Encounter Pack', + 'type:Encounter', + 'type:Session Notes', + 'type:reference', + 'type:Handbook', + 'type:Manual', + 'type:Manuals', + 'type:Compendium', + 'type:Bestiary', + + // ###################################### RPG Keywords + + // Classes / Subclasses / Archetypes + 'Class', + 'Subclass', + 'Archetype', + 'Martial', + 'Half-Caster', + 'Full Caster', + 'Artificer', + 'Barbarian', + 'Bard', + 'Cleric', + 'Druid', + 'Fighter', + 'Monk', + 'Paladin', + 'Rogue', + 'Sorcerer', + 'Warlock', + 'Wizard', + + // Races / Species / Lineages + 'Race', + 'Ancestry', + 'Lineage', + 'Aasimar', + 'Beastfolk', + 'Dragonborn', + 'Dwarf', + 'Elf', + 'Goblin', + 'Half-Elf', + 'Half-Orc', + 'Human', + 'Kobold', + 'Lizardfolk', + 'Lycan', + 'Orc', + 'Tiefling', + 'Vampire', + 'Yuan-Ti', + + // Magic / Spells / Items + 'Magic', + 'Magic Item', + 'Magic Items', + 'Wondrous Item', + 'Magic Weapon', + 'Artifact', + 'Spell', + 'Spells', + 'Cantrip', + 'Cantrips', + 'Eldritch', + 'Eldritch Invocation', + 'Invocation', + 'Invocations', + 'Pact boon', + 'Pact Boon', + 'Spellcaster', + 'Spellblade', + 'Magical Tattoos', + 'Enchantment', + 'Enchanted', + 'Attunement', + 'Requires Attunement', + 'Rune', + 'Runes', + 'Wand', + 'Rod', + 'Scroll', + 'Potion', + 'Potions', + 'Item', + 'Items', + 'Bag of Holding', + + // Monsters / Creatures / Enemies + 'Monster', + 'Creatures', + 'Creature', + 'Beast', + 'Beasts', + 'Humanoid', + 'Undead', + 'Fiend', + 'Aberration', + 'Ooze', + 'Giant', + 'Dragon', + 'Monstrosity', + 'Demon', + 'Devil', + 'Elemental', + 'Construct', + 'Constructs', + 'Boss', + 'BBEG', + + // ############################# Media / Pop Culture + 'One Piece', + 'Dragon Ball', + 'Dragon Ball Z', + 'Naruto', + 'Jujutsu Kaisen', + 'Fairy Tail', + 'Final Fantasy', + 'Kingdom Hearts', + 'Elder Scrolls', + 'Skyrim', + 'WoW', + 'World of Warcraft', + 'Marvel Comics', + 'DC Comics', + 'Pokemon', + 'League of Legends', + 'Runeterra', + 'Arcane', + 'Yu-Gi-Oh', + 'Minecraft', + 'Don\'t Starve', + 'Witcher', + 'Witcher 3', + 'Cyberpunk', + 'Cyberpunk 2077', + 'Fallout', + 'Divinity Original Sin 2', + 'Fullmetal Alchemist', + 'Fullmetal Alchemist Brotherhood', + 'Lobotomy Corporation', + 'Bloodborne', + 'Dragonlance', + 'Shackled City Adventure Path', + 'Baldurs Gate 3', + 'Library of Ruina', + 'Radiant Citadel', + 'Ravenloft', + 'Forgotten Realms', + 'Exandria', + 'Critical Role', + 'Star Wars', + 'SW5e', + 'Star Wars 5e', +]; diff --git a/client/homebrew/editor/tagInput/tagInput.jsx b/client/homebrew/editor/tagInput/tagInput.jsx index 8ed006283..c875114f5 100644 --- a/client/homebrew/editor/tagInput/tagInput.jsx +++ b/client/homebrew/editor/tagInput/tagInput.jsx @@ -1,102 +1,205 @@ import './tagInput.less'; import React, { useState, useEffect } from 'react'; -import _ from 'lodash'; +import Combobox from '../../../components/combobox.jsx'; -const TagInput = ({ unique = true, values = [], ...props })=>{ - const [tempInputText, setTempInputText] = useState(''); - const [tagList, setTagList] = useState(values.map((value)=>({ value, editing: false }))); +import tagSuggestionList from './curatedTagSuggestionList.js'; + +const TagInput = ({ tooltip, label, valuePatterns, values = [], unique = true, placeholder = '', smallText = '', onChange })=>{ + const [tagList, setTagList] = useState( + values.map((value)=>({ + value, + editing : false, + draft : '', + })), + ); useEffect(()=>{ - handleChange(tagList.map((context)=>context.value)); + const incoming = values || []; + const current = tagList.map((t)=>t.value); + + const changed = incoming.length !== current.length || incoming.some((v, i)=>v !== current[i]); + + if(changed) { + setTagList( + incoming.map((value)=>({ + value, + editing : false, + })), + ); + } + }, [values]); + + useEffect(()=>{ + onChange?.({ + target : { value: tagList.map((t)=>t.value) }, + }); }, [tagList]); - const handleChange = (value)=>{ - props.onChange({ - target : { value } - }); - }; + // substrings to be normalized to the first value on the array + const duplicateGroups = [ + ['5e 2024', '5.5e', '5e\'24', '5.24', '5e24', '5.5'], + ['5e', '5th Edition'], + ['Dungeons & Dragons', 'Dungeons and Dragons', 'Dungeons n dragons'], + ['D&D', 'DnD', 'dnd', 'Dnd', 'dnD', 'd&d', 'd&D', 'D&d'], + ['P2e', 'p2e', 'P2E', 'Pathfinder 2e'], + ]; - const handleInputKeyDown = ({ evt, value, index, options = {} })=>{ - if(_.includes(['Enter', ','], evt.key)) { - evt.preventDefault(); - submitTag(evt.target.value, value, index); - if(options.clear) { - setTempInputText(''); + const normalizeValue = (input)=>{ + const lowerInput = input.toLowerCase(); + let normalizedTag = input; + + for (const group of duplicateGroups) { + for (const tag of group) { + if(!tag) continue; + + const index = lowerInput.indexOf(tag.toLowerCase()); + if(index !== -1) { + normalizedTag = input.slice(0, index) + group[0] + input.slice(index + tag.length); + break; + } } } + + if(normalizedTag.includes(':')) { + const [rawType, rawValue = ''] = normalizedTag.split(':'); + const tagType = rawType.trim().toLowerCase(); + const tagValue = rawValue.trim(); + + if(tagValue.length > 0) { + normalizedTag = `${tagType}:${tagValue[0].toUpperCase()}${tagValue.slice(1)}`; + } + //trims spaces around colon and capitalizes the first word after the colon + //this is preferred to users not understanding they can't put spaces in + } + + return normalizedTag; }; - const submitTag = (newValue, originalValue, index)=>{ - setTagList((prevContext)=>{ - // remove existing tag - if(newValue === null){ - return [...prevContext].filter((context, i)=>i !== index); + const submitTag = (newValue, index = null)=>{ + const trimmed = newValue?.trim(); + if(!trimmed) return; + if(!valuePatterns.test(trimmed)) return; + + const normalizedTag = normalizeValue(trimmed); + + setTagList((prev)=>{ + const existsIndex = prev.findIndex((t)=>t.value.toLowerCase() === normalizedTag.toLowerCase()); + if(unique && existsIndex !== -1) return prev; + if(index !== null) { + return prev.map((t, i)=>(i === index ? { ...t, value: normalizedTag, editing: false } : t)); } - // add new tag - if(originalValue === null){ - return [...prevContext, { value: newValue, editing: false }]; - } - // update existing tag - return prevContext.map((context, i)=>{ - if(i === index) { - return { ...context, value: newValue, editing: false }; - } - return context; - }); + + return [...prev, { value: normalizedTag, editing: false }]; }); }; + const removeTag = (index)=>{ + setTagList((prev)=>prev.filter((_, i)=>i !== index)); + }; + const editTag = (index)=>{ - setTagList((prevContext)=>{ - return prevContext.map((context, i)=>{ - if(i === index) { - return { ...context, editing: true }; - } - return { ...context, editing: false }; - }); - }); + setTagList((prev)=>prev.map((t, i)=>(i === index ? { ...t, editing: true, draft: t.value } : t))); }; - const renderReadTag = (context, index)=>{ - return ( -
  • editTag(index)}> - {context.value} - -
  • - ); + const stopEditing = (index)=>{ + setTagList((prev)=>prev.map((t, i)=>(i === index ? { ...t, editing: false, draft: '' } : t))); }; - const renderWriteTag = (context, index)=>{ + const suggestionOptions = tagSuggestionList.map((tag)=>{ + const tagType = tag.split(':'); + + let classes = 'item'; + switch (tagType[0]) { + case 'type': + classes = 'item type'; + break; + case 'group': + classes = 'item group'; + break; + case 'meta': + classes = 'item meta'; + break; + case 'system': + classes = 'item system'; + break; + default: + classes = 'item'; + break; + } + return ( - handleInputKeyDown({ evt, value: context.value, index: index })} - autoFocus - /> +
    + {tag} +
    ); - }; + }); return ( -
    - -
    -
      - {tagList.map((context, index)=>{ return context.editing ? renderWriteTag(context, index) : renderReadTag(context, index); })} -
    - - setTempInputText(e.target.value)} - onKeyDown={(evt)=>handleInputKeyDown({ evt, value: null, options: { clear: true } })} - /> -
    +
    + submitTag(value)} + onEntry={(e)=>{ + if(e.key === 'Enter') { + e.preventDefault(); + submitTag(e.target.value); + } + }} + /> +
      + {tagList.map((t, i)=>t.editing ? ( + setTagList((prev)=>prev.map((tag, idx)=>(idx === i ? { ...tag, draft: e.target.value } : tag)), + ) + } + onKeyDown={(e)=>{ + if(e.key === 'Enter') { + e.preventDefault(); + submitTag(t.draft, i); // submit draft + setTagList((prev)=>prev.map((tag, idx)=>(idx === i ? { ...tag, draft: '' } : tag)), + ); + } + if(e.key === 'Escape') { + stopEditing(i); + e.target.blur(); + } + }} + autoFocus + /> + ) : ( +
    • editTag(i)}> + {t.value} + +
    • + ), + )} +
    ); }; diff --git a/client/homebrew/editor/tagInput/tagInput.less b/client/homebrew/editor/tagInput/tagInput.less index e69de29bb..e986c6cc7 100644 --- a/client/homebrew/editor/tagInput/tagInput.less +++ b/client/homebrew/editor/tagInput/tagInput.less @@ -0,0 +1,31 @@ +.tags { + + .tagInputWrap { + display:grid; + grid-template-columns: 200px 3fr; + gap:10px; + } + + .list input { + border-radius: 5px; + } + + .tagInput-dropdown { + .dropdown-options { + .item { + &.type { + background-color: #00800035; + } + &.group { + background-color: #50505035; + } + &.meta { + background-color: #00008035; + } + &.system { + background-color: #80000035; + } + } + } + } +} diff --git a/client/homebrew/editor/tagInput/tagSuggestionList.js b/client/homebrew/editor/tagInput/tagSuggestionList.js new file mode 100644 index 000000000..eb4891616 --- /dev/null +++ b/client/homebrew/editor/tagInput/tagSuggestionList.js @@ -0,0 +1,1980 @@ +export default [ + 'meta:Theme', + '5e', + 'Subclass', + 'meta:theme', + 'subclass', + 'Class', + 'Homebrew', + 'Race', + 'Dungeons and Dragons', + 'theme', + 'Daggerheart', + '2024', + 'One Piece', + 'One Piece DND', + 'Luffy', + 'Dungeons and Devil Fruits', + 'Strawhats', + 'Template', + 'Campaign Frame', + 'class', + 'Players Handbook', + 'dnd', + 'osr', + 'Dungeon Masters Guide', + 'shadowdark', + 'dragonbane', + 'PHB', + 'example', + 'Devil Fruits', + 'system:pf2e', + 'DnD', + 'DMG', + 'system:dnd5.5', + 'Monster', + 'homebrew', + 'race', + 'template', + 'Warlock', + 'monster', + 'Fighter', + 'warlock', + 'druid', + 'sorcerer', + 'D&D', + 'Magic Item', + 'Barbarian', + 'Artificer', + '2014', + 'system:descent into avernus', + 'Sorcerer', + 'Adventure', + 'Paladin', + 'Ranger', + 'user help', + 'fighter', + '5th Edition', + 'Spells', + 'Monk', + 'Spell', + 'NPC', + 'Cleric', + 'spell', + 'Rogue', + 'css', + 'Item', + 'artificer', + 'magic item', + 'Rules', + 'barbarian', + 'wizard', + 'russian', + 'DnD5e', + 'Wizard', + 'paladin', + 'bastionland', + 'spells', + 'Devil Fruit', + 'Bard', + '5.5e', + 'rogue', + 'Tabletop System', + 'Haki', + 'Druid', + 'mystic bastionland', + 'item', + 'Lore', + 'bard', + 'monk', + 'system:dnd5e', + 'world', + 'ranger', + 'WIP', + 'cleric', + 'Dragon', + 'Naruto', + 'Creature', + 'snippet', + 'npc', + 'DeS', + 'Magic', + 'guide', + 'v3', + 'Beast', + 'Classe', + 'onering', + 'Monsters', + 'Races', + 'Weapon', + 'adventure', + 'Subclasses', + 'stat block', + 'weapon', + 'Species', + 'DONE', + 'archetype', + 'RPG', + 'Hollow Knight', + '5e\'24', + 'Martial', + 'DND', + 'Classe Nova', + 'Curse of Strahd', + 'Boss', + 'Hollowed Kingdoms', + 'baldurs mouth', + '5.24', + 'Homewbrew', + 'Encyclopedia', + 'Revised', + 'OneWorldHD', + 'knight', + 'DPS', + 'srd', + 'Undead', + 'items', + 'DnD 5e', + 'Guide', + 'Compendium', + 'Feat', + 'newspaper', + 'magic', + 'TTRPG', + 'descent into avernus', + 'reference', + 'system:D&D 5e24', + 'feat', + 'Magic Items', + 'Campaign', + 'resource', + 'Feats', + 'Anime', + 'dd5', + 'races', + 'Monstrosity', + 'DM Screen', + '2024 Rules', + 'Rework', + 'Character Build', + 'Done', + '5e 2024', + 'Construct', + 'myth', + 'magic items', + 'creature', + 'Legendary', + 'Strahd', + 'background', + 'Player', + 'style', + 'Legacy', + 'Player Handbook', + 'martial', + 'Character', + 'Dungeons & Dragons', + 'Table', + 'reddit', + 'monsters', + 'OneDND', + 'dragon', + 'Suporte', + 'Soulbound', + 'Expanded Handbook', + 'bestiary', + 'Humanoid', + 'system:dnd', + 'Oredell', + 'system:class', + 'V3', + 'system:5e', + '5e\'14', + 'Age of Sigmar', + 'Items', + 'Eberron', + 'horror', + 'dnd5e', + 'star wars', + 'Background', + 'compendium', + 'revision', + 'Elemental', + 'character', + 'Marcial', + 'SW5e', + 'notes', + 'DM', + 'Fey', + 'one-shot', + 'resources', + 'NEW', + 'campaign', + 'wondrous item', + 'Setting', + 'Archive', + 'NIMRE', + 'Tanque', + 'Jogavel', + 'Dnd 5e', + 'LotM', + 'setting', + 'revised', + 'Warhammer', + 'rework', + 'Conjurador', + 'GMBinder', + 'ItemSet', + 'NPCs', + 'classes', + 'CR 2', + 'AetherSail', + 'undead', + 'Artifact', + 'cards', + 'Example', + 'Guides', + 'Theme', + 'Swamp', + 'CR 1', + 'patron', + 'Extra', + 'concept', + 'final fantasy', + 'Aberration', + 'Elder Scrolls', + 'rules', + 'meta:gratis', + 'Dice Pool', + 'Cue', + 'dark', + 'type:Style', + 'rpg', + 'meta:free', + 'summoner', + 'OC', + 'rare', + 'Fleshing Out', + 'francais', + 'Dnd', + 'Creatures', + 'Sims 4', + 'sous-classe', + 'ffxiv', + 'Underdark', + 'add-on', + 'weapons', + 'Subrace', + 'dungeons and dragons', + 'Naruto 5e', + 'Lafari', + 'Very Rare', + 'd6', + 'red', + 'Equipment', + 'CR 3', + 'Patron', + '5E', + 'objet magique', + 'spellcaster', + 'feats', + '5.24e', + 'system:d&d5e', + 'Rare', + 'Thudnfer', + 'daggerheart', + 'CR 1/2', + 'Archetype', + 'dnd 5e', + 'Pathfinder', + 'lineage', + 'Celestial', + 'Support', + 'species', + 'ARCHIVED', + 'Horror', + 'humanoid', + 'Subclase', + 'book:PHB E&E', + 'final fantasy xiv', + 'Jungle', + 'Feywild', + 'Fiend', + 'subclasses', + 'HB', + 'Legacy Challenge', + 'Project Horizon', + 'vampire', + 'WoW', + 'DND 5e', + 'Weapons', + 'system:book clone', + 'CoS', + 'N5e', + 'Summon', + 'Spellcaster', + 'Koretra', + 'Voidborn', + 'one shot', + 'Templates', + 'tables', + 'Iphexar', + 'Shattered Obelisk', + 'Sword Coast', + 'elemental', + 'lore', + 'character sheet', + 'discord', + 'BetterMonsters', + 'players', + 'group:simple skans', + 'Coastal', + 'Forest', + 'Unearthed Arcana', + 'Old', + 'Collection', + 'Ancestry', + 'Caevash', + 'Strixhaven', + 'Limbus Company', + 'Daydreams & Deviants', + 'Statblocks', + 'Urban', + 'Classes', + 'familiar', + 'Blood', + 'oneshot', + 'n5e', + 'wip', + 'masks', + 'Planeshifted', + 'Carrioss', + 'avernus', + 'object', + '1', + 'Ruins', + 'Anime Character', + 'wild shape', + 'mask', + 'dj9 game', + 'Handbook', + 'Curse', + 'oath', + 'Midralis', + 'Appendix', + '5.5', + 'tales of the valiant', + 'player classes', + 'Caster', + 'Large', + 'Fateforge', + 'Cursed', + 'beast', + 'Pathfinder 2e', + 'Design', + 'Uncommon', + 'Endeur', + 'Elemental Water', + 'SCC', + 'sci-fi', + 'Dragons', + 'human', + 'Gods', + 'Medium', + 'System', + 'Help', + 'Handout', + 'Skyrim', + 'BnB', + 'draft', + 'PC', + 'Variant', + 'syntax', + 'OneShot', + 'Clase', + 'UESTRPG', + 'Savannah', + 'Reef', + 'CR 5', + 'Forgotten Realms', + 'collection', + 'Combat', + 'Historia', + 'artifact', + 'Expansion', + 'Attunement', + 'Variant Rules', + 'd&d', + 'Party Build', + 'Evocation', + 'homerule', + 'Forbidden West', + 'how-to', + 'tov', + 'Mystical Item', + 'CR 4', + 'Necromancer', + 'General Rules', + 'Needs Update', + 'stat blocks', + 'DC Comics', + 'Sword', + 'Armor', + 'blood hunter', + 'Blood Hunter', + 'Meio Conjurador', + 'Mydia', + '3rd Party', + 'N5E', + 'Delvebound', + 'Ocean', + 'Subterranean', + 'half-caster', + 'Demon', + 'Fire', + 'meta:Template', + 'Character Sheet', + 'PF2e', + 'png', + 'fantasy', + 'Setting Guide', + 'Style', + 'Cor', + 'legacy', + 'Minion', + 'meta:khaoz age', + 'Book', + 'magical item', + 'immersion', + 'reminder cards', + 'Regras', + 'Durnovar', + '2025', + 'Camp1', + 'Abyss', + 'armor', + 'construct', + 'firearms', + 'Backgrounds', + 'Companion', + 'Melee', + 'fey', + 'Incomplete', + 'Vampire', + 'Bestiary', + 'Worldbuilding', + 'History', + 'Conjuration', + 'necromancy', + 'dragons', + 'ancestry', + 'Mech', + 'PbtA', + 'COS', + 'One Shot', + 'Factions', + 'Transmutation', + 'Spellcasting', + 'card', + 'Ardh', + 'redveil', + 'conditions', + 'elturel', + 'rhye', + 'group:James Haeck', + 'CaelYuu', + 'system:5.24e', + 'system:GM Binder', + 'Grassland', + 'melee', + 'Potions', + 'anime', + 'D&D 5e', + 'Healer', + 'Gambling', + 'Lightning', + 'fighting style', + 'support', + 'Style Template', + 'mtg', + 'NSFW', + 'aventura', + 'Manuals', + 'plant', + 'Incarnate', + 'Crafting', + 'DnDBeyond', + 'Monster Girl', + 'Monster Girl Encyclopedia', + 'pet', + 'npcs', + 'Stat Block', + 'Styleguide', + 'mitologia', + 'Objeto maravilloso', + 'vaesen rpg', + 'dnd-2024', + 'Class Handbook', + 'Space', + 'Taiga', + 'CR 6', + 'Pact Boon', + 'race/ancestry', + 'Necromancy', + 'cantrip', + 'LoL', + 'Raza', + 'handout', + 'Mechanic', + 'Conversion', + 'Wondrous Item', + 'Familiar', + 'necromancer', + 'uncommon', + 'curse', + 'Campaign Setting', + 'Tetra', + '1e', + 'module', + 'Evolving', + 'boiling sea', + 'deck', + 'OSR', + 'RU', + 'VL', + 'Underdeep', + 'Deep Ocean', + 'Giant', + 'statblock', + 'combat', + 'Time', + '5E24', + 'session zero', + 'elf', + 'tank', + 'sorcerous origin', + 'Drakkenheim', + 'Tavern', + 'Domain', + 'healer', + 'Valenor', + 'blood', + 'Oath', + 'spooky', + 'fire', + 'meta:5e24 Style', + 'Notes', + 'City', + 'Conjurador Completo', + 'prop', + 'Dotherys', + 'Rietuma 3.0', + '5e24', + 'Library of Ruina', + 'español', + 'Project Echo', + 'battle of Japan', + 'Plant', + 'Badlands', + 'Neverwinter', + 'Fantasy', + 'Beastfolk', + 'Unarmed', + 'Cold', + 'Damage', + 'attunement', + 'Hurthud', + '3rd Level', + 'spelljammer', + 'mostro', + 'Custom', + 'PT-BR', + 'Alternative Realms', + 'The Foot', + 'boss', + 'demo', + 'Supplement', + 'FitD', + 'classe', + '5.14', + 'Copy', + 'DnD5e24', + 'X-Men', + 'TNA', + 'CR 8', + 'Desert', + 'CR 7', + 'arme', + 'random', + 'spellcasting', + 'Deprecated', + 'Cards', + 'finished', + 'Ben 10', + 'equipment', + 'Geography', + 'Games', + 'For Players', + 'Faerun', + 'scroll', + 'Faction', + 'Alchemist', + 'drow', + 'Lineage', + 'mix-blend-mode', + 'columns', + 'User Help', + 'Reami Dimenticati', + 'Класс', + 'D100', + 'nsfw', + 'hucaen', + 'v1.0', + 'Cortex', + 'Fallout', + 'ww5e', + 'MAGIC', + 'DnD2024', + 'ToV', + 'D&D2024', + 'The Backrooms', + 'Freshwater', + 'D20', + 'Dragonborn', + 'custom', + 'sword', + 'Dungeons and Dragons 5e', + 'Water', + 'legendary', + 'Dungeon', + 'Ravenloft', + 'aberration', + 'Longsword', + 'transmutation', + 'Fairy Tail', + 'Character background', + 'Exandria', + 'Updated', + 'pitch', + 'Half-Caster', + 'Complete', + 'Money', + 'player', + 'forgotten-realms', + 'Festival', + 'Casino', + 'SCAG', + 'Currency', + 'North', + 'Toril', + 'Scourged Land of Valenor', + 'Oota', + 'parchment', + 'Literature', + 'Serrith', + 'PNJ', + 'Divinity Original Sin 2', + 'Wild', + 'videogame', + 'magic the gathering', + 'sweetblossom', + 'GMscreen', + 'MandM', + 'D&D 5.24', + 'Camp2', + 'Remaster', + 'riassunti', + 'type:Resource', + 'system:D&D', + 'tag:Class', + 'Excelsior', + 'Stat Blocks', + 'Sci-Fi', + 'Ooze', + 'CR 1/8', + 'sublclass', + 'chart', + 'Mountains', + 'guns', + 'Nature', + 'Orc', + 'Poison', + 'Devil', + 'fiend', + 'DC', + 'pt-br', + 'ABnB', + 'One-Shot', + 'strahd', + 'Ring', + 'Theme song', + 'orc', + 'summon', + 'Psion', + 'Psionics', + 'Dungeon Master', + 'vehicle', + 'DM only', + 'Demigod', + 'Antica Energia', + 'Pirates', + 'Sourcebook', + 'devil', + 'Cantrip', + 'mystery', + 'MtG', + 'conversion', + 'Festivals', + 'Casinos', + 'Taverns', + 'Betting', + 'Drinking', + 'phandelver', + 'Warhammer 40k', + 'mutant', + 'styling', + 'FATE', + 'Lone Wolf', + 'icon', + 'New Dawn', + 'Magic Set', + 'Paladin Subclass', + 'Alter Class', + 'difficulty classses', + 'combat tables', + 'phb', + 'Project Moon', + 'Undertomes', + 'EGO', + 'Campagne 1', + 'Constelação', + 'Arvore I', + 'Fim da Jornada', + 'greek god', + 'dwarf', + 'Firearms', + '3.5e', + 'generator', + 'Elf', + 'meta: Scenario', + 'enchantment', + 'buff', + 'ITW', + 'Tank', + 'Archived', + 'Martial Archetype', + 'caster', + 'BR', + 'Knight', + 'Utility', + 'SWADE', + 'Star Wars', + 'pc', + 'Mystic', + 'Useful', + 'Netherdeep', + 'crafting', + 'Sapient Undead', + 'Maverick', + 'Revision', + 'Resource', + 'Humblewood', + 'one piece', + 'Bag of Holding', + 'medium', + 'lightning', + 'backgrounds', + '4th Level', + 'path', + 'BREAK-RPG', + 'dark fantasy', + 'Players', + 'poison', + 'psionic', + 'gazook89', + 'homebrew subclass', + 'wild-wasteland', + 'CWD', + 'Paid', + 'Tales of the Valiant', + 'Dreadhold', + 'arma', + 'system:Mutants and Masterminds', + '#Tiefschlaf', + 'Brew', + 'Myra', + 'Swashbuckler', + 'dead by daylight', + 'Exceptional', + 'COD Zombies', + 'Hills', + 'Tundra', + 'type:Campaign', + 'wild magic', + 'Food', + 'Death', + 'homebrew rules', + 'Remake', + 'Witcher', + 'water', + 'Pet', + 'book', + 'AAH', + 'pact', + 'Ice', + 'Character Creation', + 'animal', + 'Pokemon', + 'clase', + '5e14', + 'DBZ', + 'CLONE', + 'Evil', + 'Tarsere', + 'Mythology', + 'pf2e', + 'Magical', + 'type:race', + 'Sorcerous Origin', + 'Information', + 'styles', + 'Module', + 'gish', + 'frames', + 'DeltaGreen', + 'Magic item', + 'food', + 'chef', + 'basics', + 'giant', + 'Brew Creation', + 'One-shot', + 'ttrpg', + 'Path', + 'Don\'t Starve', + 'MGE', + 'firearm', + 'DnDBehindTheScreen', + 'store', + 'The Artisan', + 'timeline', + 'college', + 'dev', + 'dungeon of the dead three', + 'Cradle', + 'Dnd5e', + 'dungeon', + 'Amaranthine', + 'Regno di Oltremare', + 'bestia', + 'rewrite', + 'WiP', + 'Subclasse', + 'mutants and masterminds', + 'The Embrace', + 'meta:documentation', + 'Mutants And Masterminds', + 'khedoria', + 'Encounter Pack', + 'giorni', + 'Statblock', + 'Enemies', + 'Goblinoids', + 'Heavens', + 'system:2e', + 'Vaalbara', + 'Dwarf', + 'airos', + 'table', + 'Artificer Specialization', + 'Buff', + 'Book 1', + 'Ranged', + 'cypher', + 'utilities', + '40k', + 'Psychic', + 'Fear', + 'steampunk', + 'shadow', + 'subclase', + 'Barbarian Subclass', + 'Elements', + 'pact boon', + 'Clan', + 'Fly', + 'solo', + 'sourcebook', + 'Marvel Comics', + 'compilation', + 'Firearm', + 'sidekick', + 'infusions', + 'Mechanics', + 'Summoner', + 'Aasimar', + 'Human', + 'Vehicle', + 'Shadow', + 'Clone', + 'custom css', + 'ocean', + 'sotdl', + 'bandit', + 'Wind', + 'Printer Friendly', + 'Obsolete', + 'mechanics', + 'illusion', + '5th edition', + 'League of Legends', + 'Vestige', + 'dungeons', + 'Dungeons', + 'and', + 'Elden Ring', + 'L5R', + 'd20', + 'Poisons', + 'd15', + 'Dungeons And Dragons', + 'MTG', + 'divine', + 'characters', + 'witch', + 'Anime Homebrew', + 'Zombie', + 'thunder', + 'Jujutsu Kaisen', + 'campagne', + 'Deadlands', + 'spell list', + '1 Person', + 'Ritual', + 'screen', + 'nature', + 'Divination', + 'Compattare', + 'dtrpg', + 'quick ref', + 'Mago', + 'Illivia', + 'Shonen', + 'Core Deities', + 'green ronin', + 'Bless', + 'D&D5e', + 'version:0.1.0', + 'curato', + 'system:Ord', + 'Images', + 'Sealed Artifact', + 'Giants', + 'CR 9', + 'CR 11', + 'CR 0', + 'CR 14', + 'Shadowfell', + 'Tier 1', + 'd100', + 'Elemental Air', + 'artificiel', + 'Cultist', + 'Cyberpunk', + 'Huge', + 'Warrior', + 'Gun', + 'quest', + 'LYRA', + 'Music', + 'Tiefling', + 'Master', + 'Witch', + 'Linnorm', + '1st-level', + 'Mount', + 'Animal', + 'Comics', + 'Superhero', + 'creatures', + 'Hunter', + 'Control', + 'Dragon Ball', + 'Dragon Ball Z', + 'Dagger', + 'questingforamonster', + 'ICRPG', + 'Booklet', + 'f and t', + 'common', + 'Chaos', + 'spellblade', + 'Constitution', + 'artisan', + 'arcane', + 'Released', + 'ring', + 'runes', + 'gun', + 'Supportive Material', + 'The Witcher', + 'Desarmado', + 'Monster Monday', + 'Bleach', + 'Demon Slayer', + 'mice', + 'worldbuilding', + 'Necrotic', + 'ability score', + 'demon', + 'Armybook Shivatiano', + 'warrior', + 'Fighter Subclass', + 'system', + 'whisperveil', + 'psychic', + 'warhammer', + 'Aventura', + 'Culture', + 'Material', + 'meta:npc', + 'shops', + 'magic weapon', + 'nhera', + 'Dark Fantasy', + 'Regles', + 'Wonderous Item', + 'Features', + 'pokemon', + 'Ghosts of Saltmarsh', + 'monstrosity', + 'DL TWW', + 'companion', + 'alternate layout', + 'Tutorials', + 'Kitsune', + 'don', + 'heroique', + 'mini campaign', + 'drago', + 'Aquatic', + 'tool', + 'handmade', + 'released', + 'Spellblade', + 'pregen', + 'level 2', + 'Baldurs gate 3', + 'My Hero', + 'Technically a subclass', + '5.24e Remastered Subclasses', + 'dinosaurs', + '5E.2024', + 'Razas', + 'Horizon', + 'Clothing', + '+2', + 'castellano', + 'pentacle prophecy', + 'tag:Spells', + 'gruppo A', + 'Rpg', + 'razze', + 'type:Adventure', + 'unfinished', + '3.5', + 'gunslinger', + 'BBEG', + 'Arcane', + 'component', + 'Bow', + 'backstory', + 'phandalin', + 'Skills', + 'Pact', + 'Elemental Earth', + 'Joke', + 'invocation', + 'martial class', + 'Super Villain', + 'Eldritch', + 'Elemental Fire', + 'Homebrew Class', + 'eldritch', + 'cyberpunk', + 'Player Race', + 'Class Mod', + 'Heatcoast', + 'meta:Guide', + 'Yemao', + 'evil', + 'Named NPC', + 'CLASS', + 'Angel', + 'vecna', + 'PT', + 'PTBR', + 'Ancient', + 'Small', + 'WotC Style', + '5e Homebrew', + '1st Level', + 'dagger', + 'Brancalonia', + 'encounter', + 'cat', + 'primal path', + 'Ambientazione', + 'Magie', + 'candlekeep', + 'Ongoing', + 'Oneshot', + 'Wondrous', + 'Janbrewery', + 'Tattoos', + '5e (2014)', + 'concentration', + 'very rare', + 'Set', + 'Kobold', + 'martial archetype', + 'God', + 'blog', + 'New Gate', + 'Healing', + 'OneDnD', + 'Incantesimi', + 'Player Options', + 'contest', + 'pirate', + 'Manuel', + 'Alchimie', + 'Herboristerie', + 'Ingredients', + 'starlost', + 'Campaign 1', + 'Abandoned', + 'Previous Editions', + 'Enchantment', + 'Tools', + 'Oblivion', + 'domain', + '5th Level', + 'DnD Beyond', + 'Reference', + 'Sorcerer Subclass', + 'Dragon Magazine', + 'feature', + 'german', + 'conjuration', + 'strixhaven', + 'Sentient', + 'JJK', + '10 Generations', + 'character creation', + 'LevelUp', + 'pallid grove', + 'primer', + 'Requires Attunement', + 'College', + 'Aesthetic', + 'critter', + 'home game', + 'spanish', + 'stats', + 'Lairon', + 'Hunters Guild', + 'original setting', + 'Bosses', + 'Radiant Citadel', + 'actions', + 'Reworked', + 'Elystera', + 'Wyvern', + 'vikings', + 'thief', + 'enemies', + 'Obsession', + 'Yi Sang', + 'aberrazione', + 'Limbus', + 'animals', + 'minecraft', + 'mice of legend', + 'osric', + '20 Minutes Till Dawn', + 'campaign frame', + 'latigo', + 'DH', + 'Eldritch Invocation', + 'system:daggerheart', + '100ni', + 'meta:Sheet', + 'fa-solid fa-sheet-plastic:Ficha', + 'tag:Berean', + 'AD&D', + 'B/X', + 'The Codex Of Anomalous Entities', + 'monster manual', + 'Polar Waters', + 'CR 12', + 'CR 10', + 'blood magic', + 'Gunslinger', + 'grimoire', + 'Drakes', + 'Japanese', + 'subrace', + 'ooze', + 'Stats', + 'Half Caster', + 'Sea', + 'time', + 'Brawler', + 'Session 0', + 'Halloween', + 'Runeterra', + 'Divine', + 'Random', + 'Lifestar', + 'arcane trickster', + 'Paddy4530', + 'evocation', + 'light', + 'Steampunk', + 'shaman', + 'Primal Path', + 'monk subclass', + 'Full Caster', + 'World', + 'Planning', + 'spirit', + 'Nova Era', + 'abjuration', + 'Christmas', + 'Critical Role', + 'Gish', + 'Bandit', + 'Monster Manual', + 'party member', + 'mgazt', + 'Playable Race', + 'Donjon.bin.sh', + 'Final Fantasy', + 'Roleplay', + 'monstre', + 'fairy', + 'frame', + 'Minecraft', + 'Stealth', + 'Manual', + 'half caster', + 'Storm', + 'Sorcery', + 'format work', + 'Kingdom Hearts', + 'hexblade', + 'block', + 'page layouts', + 'Monk Subclass', + 'FinyaFluKaiKolja', + 'Radiant', + 'group:playtest', + 'Korrahir', + 'noble', + 'exorcist', + 'xapien', + 'Raven Queen', + 'markdown', + 'damage', + 'Alchemy', + 'morrigan', + 'genasi', + 'ZNH', + 'folklore', + 'Fate', + 'hechicero', + 'Air', + 'Magic Weapon', + 'Anime DND 5e', + 'Dragon Ball Z TTRPG', + 'Dragon Ball Z RPG', + 'Dragon Ball Z DND', + 'Dragon Ball Z 5e', + 'samurai', + 'Goblin', + 'Base Sheet', + 'Shackled City Adventure Path', + 'Natureza', + 'control', + 'Normarch', + 'Reddit', + 'Genshin Impact', + 'Abjuration', + 'Myr', + 'Flight', + 'Vampyre', + 'nightmare', + 'Lycan', + 'Occult', + 'circle', + 'Christmas Special', + 'DoDD', + 'Character Options', + 'traduction', + 'Characters', + 'Gear', + 'system:sf2e', + 'drakkenheim', + 'downtime', + 'amulet', + 'Feiticeiros e Maldicoes', + 'Tecnica amaldicoada', + 'prorpg', + 'enemy', + 'No Mercy', + 'rain world', + 'slugcat', + 'fly', + 'meta:User Guide', + 'Fallout TTRPG', + 'regles', + 'Ill Tides', + 'Light-hearted', + 'Vastria', + 'school', + 'Fillible Online', + 'Mezgarr', + 'Berserk', + 'invocations', + 'Classe Refeita', + 'Auroboros', + 'bosses', + 'fabula ultima', + 'Shagya', + 'wild', + 'DnD 2024', + 'KaiburrKathHound', + 'Barbarian Path', + 'fauna', + '5E.2014', + 'system:curse of strahd', + 'Unofficial', + 'how to', + 'Glaive', + 'A5E', + 'pt', + 'Consumible', + 'Realmers\'', + 'Versatile Lineage', + 'Shichibukai', + '2024e', + 'Rencontre', + 'tag:Spell List', + 'elementalist', + 'noncaster', + 'blasphemous', + 'Mordhiem', + 'Wildfrost', + '#Regelwerk', + 'Rewrite', + 'Maldición de Strahd', + 'Scion', + 'Entities', + 'Hoarwyrm', + 'Player utility', + 'CR 1/4', + 'Temperate Forest', + 'Demons', + 'Drow', + 'type:rules', + 'fay', + '2e', + 'familier', + 'supplement', + 'Amberwar', + 'slime', + 'Lycanthropy', + 'meta: Terres de Leyt', + 'Strong', + 'AAH Vol. 1', + 'Force', + 'Jump', + 'Aboleths', + 'lol', + 'location', + 'small', + 'customizable', + 'Modern', + 'Sky', + 'portugues', + 'Hero', + 'Villain', + 'element', + 'Tyranny of Dragons', + 'Adventure Guide', + 'New Class', + 'Witchlight', + 'Shardblade', + 'Plateaux', + 'WOTC', + 'Snippet', + 'Terra', + 'Otherworldly Patron', + 'ritual', + 'hag', + 'Cyberpunk 2077', + 'tavern', + 'Artificer Specialist', + 'Werewolf', + 'Boesia', + 'vampiric', + 'monastic tradition', + 'Gothic', + 'celestial', + 'Unfinished', + 'Core', + 'Arcane Tradition', + 'Troll', + 'Origin', + 'Draconic', + 'dj9 member', + 'test', + 'Hag', + 'gem', + 'Invocations', + 'Dark Sun', + 'aarkhen', + 'How to', + 'ravenloft', + 'faerie', + 'Playtest', + 'Shaman', + 'dead', + 'Tomba Aniquilacio', + 'Pacto', + 'fullcaster', + 'Electric', + 'Ability Score', + '4D', + 'pathfinder', + 'insect', + 'hook', + 'page layout', + 'healing', + 'Lineages', + 'Flying', + 'Martial Arts', + 'journal', + 'Aide de jeu', + 'hunter', + 'headers', + 'Dark Souls', + 'courtyard', + 'crossroads', + 'Quest', + 'CotF', + 'defense', + 'Semryss', + 'invoked class', + 'Session Notes', + 'goblin', + 'infernal', + 'fate', + 'oni', + 'spellbook', + 'Summoning', + 'slut', + 'whore', + 'Greyhawk', + 'Mobility', + 'Reddit Remake', + 'Guild', + 'Cosmic Mart', + '7th Level', + 'dragonborn', + 'curse of strahd', + 'Ranger Subclass', + 'dossier', + 'dossie', + 'de', + 'pnpde', + 'Plane Shift', + 'halloween', + 'group:aventura', + '9th Level', + 'tome', + 'cold', + 'acid', + 'deprecated', + 'mind flayer', + 'MECHA', + 'EssentialsKit', + '2d6', + 'ToD', + 'Work In Progress', + 'Bond', + 'Versatile', + 'Dead', + 'SYWTBAGM', + 'summoning', + 'english', + 'Eilistraee', + 'Draft', + 'DoD', + 'map', + 'Frightened', + 'Psychic Damage', + 'eberron', + 'recompensa', + 'wizard subclass', + 'teiran', + 'Saltmarsh', + 'jp setting', + 'Illithid', + 'Longbow', + 'hell', + 'Monarch', + 'type:feat', + 'reglas', + 'cooking', + 'Abenteuer', + 'reloaded', + 'incompleto', + 'mecanica', + 'Location', + 'Grimlores Grimoire', + '2024 Subclass', + 'Chiesa di Toleno', + 'finalfantasy', + 'The Undertomes', + 'Lobotomy Corporation', + 'SDHTA', + 'D&D 2024', + 'other', + 'ally', + 'images', + 'Player\'s Guide', + 'Avalon Sword', + 'Cael\'Yuu', + 'dnd-2014', + 'Regelwerk', + 'Español', + 'br', + 'dnd 5.0', + 'monstro', + 'grand cemetery', + 'Phoenix', + 'dnd 2024', + 'Bloodhunter', + 'Sintonizacion', + 'dungeons & dragons', + 'Fix', + 'Rulebook', + 'Shadowdark', + 'heroic', + 'HFW', + 'Earthdawn', + '24e', + 'cormyr', + 'suzail', + 'dc20', + 'tag:Rules', + 'The Griffon\'s Saddlebag', + 'LOTM', + 'tag:Adventure', + 'drunken master', + 'eldritch invocation', + 'Персонаж', + 'Orcs', + 'Lizardfolk', + 'Frostfell', + 'CR 17', + 'Shapechanger', + 'Farmland', + 'Mages', + 'Any', + 'CR 13', + 'Earth', + 'Mountain', + 'Drake', + 'transformation', + 'GM', + 'Lich', + 'lovecraft', + 'unique', + 'Optional Rules', + 'int', + 'creator', + 'Primal', + 'simple', + 'golem', + 'Void', + 'Armour', + 'spellsword', + 'General', + 'Asian', + 'Bringers of chaos', + 'Optional Feature', + 'subraces', + 'Galanoth', + 'barbarian subclass', + 'felhearth', + 'modular', + 'Vampires', + 'wysteria', + 'adaptation', + 'beasts', + 'naruto', + 'ninja', + 'Psionic', + 'Guns', + 'Crystal', + 'Guardian', + 'NonProfit', + 'Mimic', + 'languages', + 'Epic Boons', + 'Primer', + 'Icewind Dale', + 'joke', + 'lycan', + 'CR3', + 'Armors', + 'ff7', + 'materia', + 'final fantasy 7 remake', + 'esper', + 'ff7 remake', + 'gargantuan', + 'Frog', + 'CR5', + 'blank', + 'monster hunter', + 'league of legends', + 'french', + 'Pokémon', + 'kobold', + 'soul', + 'ffxi', + 'd10', + 'Roman', + 'Cute', + 'DD5', + 'variant', + 'tree', + 'fr', + 'Scenario', + 'lycanthrope', + 'druide', + 'staff', + 'eios', + 'arkheneios', + 'Runic', + 'Work', + 'Ukrainian', + 'cover-page', + 'mage', + 'deities', + 'gods', + 'Boss Fight', + 'Lair', + 'WBTW', + 'roguish archetype', + 'Character Option', + 'Shortsword', + 'Illrigger', + 'Bloodborne', + 'cr6', + 'Priest', + 'Hamon', + 'Toonkind', + 'rol', + 'Strength', + 'forgotten realms', + 'Spanish', + 'Conclave', + 'Electro', + 'Magical Tattoos', + 'Matt Mercer', + 'Wildemount', + 'Mighty Nien', + 'Campaign 2', + 'Resistances', + 'Bug', + 'impression', + 'PF', + 'Magnus Archives', + 'ice', + 'speed', + 'Generic NPC', + 'Titanic', + 'Ink Friendly', + 'bleed', + 'elder scrolls', + 'Immortal', + 'LMOP', + 'Travel', + 'Olphus', + '3d6', + 'heist', + 'World History', + 'ghost', + 'genie', + 'kids on bikes', + 'Russia', + 'conclave', + 'overhaul', + 'manual', + 'Adventures In Eden', + 'Downtime', + 'hamon', + 'cloak', + 'shadowfell', + 'Hellfire', + 'Paladin Oath', + 'Genshin', + 'Nation', + 'air', + 'Magical Item', + 'War', + 'Original', + 'Monstrous Compendium', + 'Calamity', + 'Warden', + 'Apocalypse', + 'shield', + 'AC', + 'expansion', + 'Concentration', + 'charm', + 'Weave', + 'lycanthropy', + 'raza', + 'far realm', + 'fighter subclass', + 'ita', + 'Pirate', + 'Laranja', + 'Grapple', + 'EastByForce', + 'hobgoblin', + 'oneshot-notes', + 'Holy', + 'optional', + 'type:cenario', + 'group:core', + 'The Brewery', + 'Alcance', + 'Morrowind', + 'Indigo', + 'Divino', + '2nd Level', + 'Sub-Class', + 'cantrips', + 'Cloak', + 'battle master', + 'Dark', + 'Puzzle', + 'Lucky', + 'consumable', + 'rebalance', + 'Shove', + 'Area Control', + 'Vanguard', + 'funny', + 'e5', + 'Dragonlance', + 'psion', + 'initiative', + 'Tactician', + 'Inspiration', + 'artificier', + 'way', + 'inspired', + 'historia', + 'Medusa', + '2 part', + 'holy', + 'gift', + 'Nimble', + 'mostri', + 'phoenix', + 'travel', + 'Class Template', + 'Intimidation', + 'constructs', + 'P666', + 'Formatting', + 'Divinity', + 'Rod', + 'Language', + 'yokai', + 'rune', + 'western', + 'vampires', + 'flying', + 'cute', + 'Enemy', + 'boon', + 'Tables', + 'ShadowFight', + 'meta: Theme', + 'SCS', + 'vanthampur villa', + 'CoA', + 'shop', + 'destiny', + 'magical weapon', + 'Arcane Arcade', + 'XP to Level 3', + 'Dice Average RPG', + 'Pip-Boy', + 'Dragon Heist', + 'session notes', + 'tattoo', + 'flick', + 'P6:66', + 'Comic Character', + 'experiment', + 'Minerva', + 'type:Spellbook', + 'Realmfall', + 'Wand', + 'halfling', + 'sw5e', + 'implementar AP', + 'Mask', + 'Gazook89', + 'Weltenrauch-Chroniken', + 'MiA', + 'Made in Abyss', + 'français', + 'fae', + 'Lemuria', + 'Mork Borg', + 'guerrier', + 'prunus', + 'condition', + 'pf2', + 'tr', + 'costrutto', + 'German', + 'project moon', + '5r', + 'galles', + 'Project moon', + 'Yisang', + 'Spicebush', + 'player-accessible', + 'Especie', + 'Westmarch', + 'a', + 'Cart', + 'Magus', + 'group:Mchael Galvis', + 'tip', + 'werewolf', + 'mundane', + 'garrett', + 'unarmed', + 'Arcane Odyssey', + 'Tomb of Divinity', + 'pets', + 'Video Game', + '4 part', + 'pbta', + 'Druids', + 'multiclass', + 'manuale', + 'mimic', + 'plane shift', + 'Dotes', + 'Hechizos', + 'Infernal', + 'Enhanced', + 'done', + 'Mission report', + 'Blanks', + 'Masks', + 'Ultimate Ability', + 'shadow-slave', + 'Advertising', + 'transform', + 'Fullmetal Alchemist', + 'Fullmetal Alchemist Brotherhood', + 'tag:TAoF&F', + 'Dwarves', + 'Humans', + 'Nine Hells', + 'Devils', + 'Archons', + 'CR 15', + 'Troglodytes', + 'Goliath', + 'retired', + 'boots', + 'ranged', + 'shields', + 'Zhentarim', + 'World of Warcraft', + 'Frontline', + 'Guildmaster\'s Guide to Ravnica', + 'Dungeons & Dragons 5e', + 'beholder', + 'NEEDS FIXING', + 'mechanic', + 'Loot', + 'champion', + 'Runes', + 'Shield', + 'Punch', + 'Sniper', + 'Magical Girl', + 'NotDND', + 'story', + 'Sleep', + 'Bard College', + 'Illusion', + 'Thunder', + 'Defender', + 'Genasi', + 'troll', + 'Gehenna', + 'Yugoloth', + 'social', + 'Player Class', + 'homebrew class', + 'CR 16', + 'Ghost', + 'Kobolds', + 'Trolls', + 'Yuan-Ti', + 'Elder Scrolls Offline', + 'armure', + 'Mage', + 'CR 18', + 'Technology', + 'Mystery', + 'darkness', + 'Airship', + 'New Campaign', + 'Warframe', + 'Wizard Subclass', + 'Gold', + 'Candor', + 'Overhaul', + 'Dragon Knight', + 'Enoreth', + 'Artifacts', + 'New', + 'AMMO', + 'Campagne', + 'Valbise', + 'Subclasseptember', + 'Mecha', + 'Yu-Gi-Oh', + 'Goblinoid', + 'underwater', + 'SW5E', + 'bardo' +]; \ No newline at end of file diff --git a/client/homebrew/homebrew.jsx b/client/homebrew/homebrew.jsx index 326287ee6..9ab69074b 100644 --- a/client/homebrew/homebrew.jsx +++ b/client/homebrew/homebrew.jsx @@ -1,8 +1,7 @@ - -import 'core-js/es/string/to-well-formed.js'; //Polyfill for older browsers +import 'core-js/es/string/to-well-formed.js'; // Polyfill for older browsers import './homebrew.less'; import React from 'react'; -import { StaticRouter as Router, Route, Routes, useParams, useSearchParams } from 'react-router'; +import { BrowserRouter as Router, Routes, Route, useParams, useSearchParams } from 'react-router'; import { updateLocalStorage } from './utils/updateLocalStorage/updateLocalStorageKeys.js'; @@ -41,24 +40,21 @@ const Homebrew = (props)=>{ brews } = props; - global.account = account; - global.version = version; - global.config = config; - const backgroundObject = ()=>{ - if(global.config.deployment || (config.local && config.development)){ - const bgText = global.config.deployment || 'Local'; - return { - backgroundImage : `url("data:image/svg+xml;utf8,${bgText}")` - }; + if(config?.deployment || (config?.local && config?.development)) { + const bgText = config?.deployment || 'Local'; + return { + backgroundImage : `url("data:image/svg+xml;utf8,${bgText}")` + }; } return null; }; + updateLocalStorage(); return ( - -
    + +
    } /> } /> @@ -80,4 +76,4 @@ const Homebrew = (props)=>{ ); }; -module.exports = Homebrew; \ No newline at end of file +export default Homebrew; diff --git a/client/homebrew/homebrew.less b/client/homebrew/homebrew.less index 2cbc35857..9bafadffe 100644 --- a/client/homebrew/homebrew.less +++ b/client/homebrew/homebrew.less @@ -1,4 +1,4 @@ -@import 'naturalcrit/styles/core.less'; +@import '@sharedStyles/core.less'; .homebrew { height : 100%; background-color:@steel; diff --git a/client/homebrew/main.jsx b/client/homebrew/main.jsx new file mode 100644 index 000000000..635729d49 --- /dev/null +++ b/client/homebrew/main.jsx @@ -0,0 +1,6 @@ +import { createRoot } from 'react-dom/client'; +import Homebrew from './homebrew.jsx'; + +const props = window.__INITIAL_PROPS__ || {}; + +createRoot(document.getElementById('reactRoot')).render(); diff --git a/client/homebrew/navbar/account.navitem.jsx b/client/homebrew/navbar/account.navitem.jsx index 8c0e92023..0be06c471 100644 --- a/client/homebrew/navbar/account.navitem.jsx +++ b/client/homebrew/navbar/account.navitem.jsx @@ -97,7 +97,7 @@ const Account = createReactClass({ // Logged out // LOCAL ONLY - if(global.config.local) { + if(global.config?.local) { return login ; diff --git a/client/homebrew/navbar/error-navitem.less b/client/homebrew/navbar/error-navitem.less index 637ddac95..4da665915 100644 --- a/client/homebrew/navbar/error-navitem.less +++ b/client/homebrew/navbar/error-navitem.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/core.less'; + .navItem.error { position : relative; background-color : @red; diff --git a/client/homebrew/navbar/navbar.jsx b/client/homebrew/navbar/navbar.jsx index e75be8d59..db9a836c9 100644 --- a/client/homebrew/navbar/navbar.jsx +++ b/client/homebrew/navbar/navbar.jsx @@ -8,16 +8,10 @@ import PatreonNavItem from './patreon.navitem.jsx'; const Navbar = createReactClass({ displayName : 'Navbar', getInitialState : function() { - return { - //showNonChromeWarning : false, - ver : '0.0.0' - }; - }, - - getInitialState : function() { - return { - ver : global.version - }; + return { + // showNonChromeWarning: false, // uncomment if needed + ver : global.version || '0.0.0' + }; }, /* diff --git a/client/homebrew/navbar/navbar.less b/client/homebrew/navbar/navbar.less index 7b0217bf8..eb518e808 100644 --- a/client/homebrew/navbar/navbar.less +++ b/client/homebrew/navbar/navbar.less @@ -1,4 +1,4 @@ -@import 'naturalcrit/styles/colors.less'; +@import '@sharedStyles/core.less'; @navbarHeight : 28px; @viewerToolsHeight : 32px; diff --git a/client/homebrew/navbar/newbrew.navitem.jsx b/client/homebrew/navbar/newbrew.navitem.jsx index 4664d509b..ac72121f1 100644 --- a/client/homebrew/navbar/newbrew.navitem.jsx +++ b/client/homebrew/navbar/newbrew.navitem.jsx @@ -1,7 +1,7 @@ import React from 'react'; import _ from 'lodash'; import Nav from './nav.jsx'; -import { splitTextStyleAndMetadata } from '../../../shared/helpers.js'; +import { splitTextStyleAndMetadata } from '@shared/helpers.js'; const BREWKEY = 'HB_newPage_content'; const STYLEKEY = 'HB_newPage_style'; diff --git a/client/homebrew/navbar/print.navitem.jsx b/client/homebrew/navbar/print.navitem.jsx index e7a6ff053..ea262cf03 100644 --- a/client/homebrew/navbar/print.navitem.jsx +++ b/client/homebrew/navbar/print.navitem.jsx @@ -1,6 +1,6 @@ import React from 'react'; import Nav from './nav.jsx'; -import { printCurrentBrew } from '../../../shared/helpers.js'; +import { printCurrentBrew } from '@shared/helpers.js'; export default function(){ return diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less index d335f3ca9..93685947c 100644 --- a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less +++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less @@ -1,3 +1,4 @@ +@import '@sharedStyles/core.less'; .brewItem { position : relative; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index fa33e2863..176158e2c 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -4,34 +4,35 @@ import './editPage.less'; // Common imports import React, { useState, useEffect, useRef } from 'react'; import request from '../../utils/request-middleware.js'; -import Markdown from '../../../../shared/markdown.js'; +import Markdown from '@shared/markdown.js'; import _ from 'lodash'; import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js'; -import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '../../../../shared/helpers.js'; +import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; import SplitPane from '../../../components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import NewBrewItem from '../../navbar/newbrew.navitem.jsx'; -import AccountNavItem from '../../navbar/account.navitem.jsx'; -import ErrorNavItem from '../../navbar/error-navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; -import VaultNavItem from '../../navbar/vault.navitem.jsx'; -import PrintNavItem from '../../navbar/print.navitem.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import NewBrewItem from '@navbar/newbrew.navitem.jsx'; +import AccountNavItem from '@navbar/account.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import VaultNavItem from '@navbar/vault.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; // Page specific imports -import { Meta } from 'vitreum/headtags'; +import Headtags from '../../../../vitreum/headtags.js'; +const Meta = Headtags.Meta; import { md5 } from 'hash-wasm'; import { gzipSync, strToU8 } from 'fflate'; import { makePatches, stringifyPatches } from '@sanity/diff-match-patch'; -import ShareNavItem from '../../navbar/share.navitem.jsx'; +import ShareNavItem from '@navbar/share.navitem.jsx'; import LockNotification from './lockNotification/lockNotification.jsx'; import { updateHistory, versionHistoryGarbageCollection } from '../../utils/versionHistory.js'; import googleDriveIcon from '../../googleDrive.svg'; @@ -56,28 +57,28 @@ const EditPage = (props)=>{ ...props }; - const [currentBrew , setCurrentBrew ] = useState(props.brew); - const [isSaving , setIsSaving ] = useState(false); - const [lastSavedTime , setLastSavedTime ] = useState(new Date()); - const [saveGoogle , setSaveGoogle ] = useState(!!props.brew.googleId); - const [error , setError ] = useState(null); - const [HTMLErrors , setHTMLErrors ] = useState(Markdown.validate(props.brew.text)); - const [currentEditorViewPageNum , setCurrentEditorViewPageNum ] = useState(1); + const [currentBrew, setCurrentBrew] = useState(props.brew); + const [isSaving, setIsSaving] = useState(false); + const [lastSavedTime, setLastSavedTime] = useState(new Date()); + const [saveGoogle, setSaveGoogle] = useState(!!props.brew.googleId); + const [error, setError] = useState(null); + const [HTMLErrors, setHTMLErrors] = useState(Markdown.validate(props.brew.text)); + const [currentEditorViewPageNum, setCurrentEditorViewPageNum] = useState(1); const [currentEditorCursorPageNum, setCurrentEditorCursorPageNum] = useState(1); const [currentBrewRendererPageNum, setCurrentBrewRendererPageNum] = useState(1); - const [themeBundle , setThemeBundle ] = useState({}); - const [unsavedChanges , setUnsavedChanges ] = useState(false); - const [alertTrashedGoogleBrew , setAlertTrashedGoogleBrew ] = useState(props.brew.trashed); - const [alertLoginToTransfer , setAlertLoginToTransfer ] = useState(false); - const [confirmGoogleTransfer , setConfirmGoogleTransfer ] = useState(false); - const [autoSaveEnabled , setAutoSaveEnabled ] = useState(true); - const [warnUnsavedChanges , setWarnUnsavedChanges ] = useState(true); + const [themeBundle, setThemeBundle] = useState({}); + const [unsavedChanges, setUnsavedChanges] = useState(false); + const [alertTrashedGoogleBrew, setAlertTrashedGoogleBrew] = useState(props.brew.trashed); + const [alertLoginToTransfer, setAlertLoginToTransfer] = useState(false); + const [confirmGoogleTransfer, setConfirmGoogleTransfer] = useState(false); + const [autoSaveEnabled, setAutoSaveEnabled] = useState(true); + const [warnUnsavedChanges, setWarnUnsavedChanges] = useState(true); const editorRef = useRef(null); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); const saveTimeout = useRef(null); const warnUnsavedTimeout = useRef(null); - const trySaveRef = useRef(trySave); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew + const trySaveRef = useRef(null); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew const unsavedChangesRef = useRef(unsavedChanges); // Similarly, onBeforeUnload lives outside React and needs ref to unsavedChanges useEffect(()=>{ diff --git a/client/homebrew/pages/errorPage/errorPage.jsx b/client/homebrew/pages/errorPage/errorPage.jsx index ffbfc43bb..837775b97 100644 --- a/client/homebrew/pages/errorPage/errorPage.jsx +++ b/client/homebrew/pages/errorPage/errorPage.jsx @@ -1,7 +1,7 @@ import './errorPage.less'; import React from 'react'; import UIPage from '../basePages/uiPage/uiPage.jsx'; -import Markdown from '../../../../shared/markdown.js'; +import Markdown from '@shared/markdown.js'; import ErrorIndex from './errors/errorIndex.js'; const ErrorPage = ({ brew })=>{ diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 36f6f8162..580d69e76 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -1,33 +1,34 @@ -/* eslint-disable max-lines */ + import './homePage.less'; // Common imports import React, { useState, useEffect, useRef } from 'react'; import request from '../../utils/request-middleware.js'; -import Markdown from '../../../../shared/markdown.js'; +import Markdown from '@shared/markdown.js'; import _ from 'lodash'; import { DEFAULT_BREW } from '../../../../server/brewDefaults.js'; -import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '../../../../shared/helpers.js'; +import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; import SplitPane from '../../../components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import NewBrewItem from '../../navbar/newbrew.navitem.jsx'; -import AccountNavItem from '../../navbar/account.navitem.jsx'; -import ErrorNavItem from '../../navbar/error-navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; -import VaultNavItem from '../../navbar/vault.navitem.jsx'; -import PrintNavItem from '../../navbar/print.navitem.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import NewBrewItem from '@navbar/newbrew.navitem.jsx'; +import AccountNavItem from '@navbar/account.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import VaultNavItem from '@navbar/vault.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; // Page specific imports -import { Meta } from 'vitreum/headtags'; +import Headtags from '@vitreum/headtags.js'; +const Meta = Headtags.Meta; const BREWKEY = 'homebrewery-new'; const STYLEKEY = 'homebrewery-new-style'; @@ -44,16 +45,16 @@ const HomePage =(props)=>{ ...props }; - const [currentBrew , setCurrentBrew] = useState(props.brew); - const [error , setError] = useState(undefined); - const [HTMLErrors , setHTMLErrors] = useState(Markdown.validate(props.brew.text)); - const [currentEditorViewPageNum , setCurrentEditorViewPageNum] = useState(1); + const [currentBrew, setCurrentBrew] = useState(props.brew); + const [error, setError] = useState(undefined); + const [HTMLErrors, setHTMLErrors] = useState(Markdown.validate(props.brew.text)); + const [currentEditorViewPageNum, setCurrentEditorViewPageNum] = useState(1); const [currentEditorCursorPageNum, setCurrentEditorCursorPageNum] = useState(1); const [currentBrewRendererPageNum, setCurrentBrewRendererPageNum] = useState(1); - const [themeBundle , setThemeBundle] = useState({}); - const [unsavedChanges , setUnsavedChanges] = useState(false); - const [isSaving , setIsSaving] = useState(false); - const [autoSaveEnabled , setAutoSaveEnable] = useState(false); + const [themeBundle, setThemeBundle] = useState({}); + const [unsavedChanges, setUnsavedChanges] = useState(false); + const [isSaving, setIsSaving] = useState(false); + const [autoSaveEnabled, setAutoSaveEnable] = useState(false); const editorRef = useRef(null); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); diff --git a/client/homebrew/pages/homePage/homePage.less b/client/homebrew/pages/homePage/homePage.less index b89c2c7dd..fd072c1e1 100644 --- a/client/homebrew/pages/homePage/homePage.less +++ b/client/homebrew/pages/homePage/homePage.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/core.less'; + .homePage { position : relative; a.floatingNewButton { diff --git a/client/homebrew/pages/homePage/welcome_msg.md b/client/homebrew/pages/homePage/welcome_msg.md index 49d1918f0..d4d6bed05 100644 --- a/client/homebrew/pages/homePage/welcome_msg.md +++ b/client/homebrew/pages/homePage/welcome_msg.md @@ -36,7 +36,7 @@ After clicking the "Print" item in the navbar a new page will open and a print d If you want to save ink or have a monochrome printer, add the **PRINT → {{fas,fa-tint}} Ink Friendly** snippet to your brew! }} -![homebrew mug](https://i.imgur.com/hMna6G0.png) {position:absolute,bottom:20px,left:130px,width:220px} +![homebrew mug](https://homebrewery.naturalcrit.com/assets/homebrewerymug.png) {position:absolute,bottom:20px,left:130px,width:220px} {{artist,bottom:160px,left:100px ##### Homebrew Mug @@ -77,16 +77,16 @@ If you wish to sell or in some way gain profit for what's created on this site, If you'd like to credit us in your brew, we'd be flattered! Just reference that you made it with The Homebrewery. ### More Homebrew Resources -[![Discord](/assets/discordOfManyThings.svg){width:50px,float:right,padding-left:10px}](https://discord.gg/by3deKx) +[![Discord](https://homebrewery.naturalcrit.com/assets/discordOfManyThings.svg){width:50px,float:right,padding-left:10px}](https://discord.gg/by3deKx) If you are looking for more 5e Homebrew resources check out [r/UnearthedArcana](https://www.reddit.com/r/UnearthedArcana/) and their list of useful resources [here](https://www.reddit.com/r/UnearthedArcana/wiki/resources). The [Discord Of Many Things](https://discord.gg/by3deKx) is another great resource to connect with fellow homebrewers for help and feedback. {{position:absolute;top:20px;right:20px;width:auto -[![Discord](/assets/discord.png){height:30px}](https://discord.gg/by3deKx) -[![Github](/assets/github.png){height:30px}](https://github.com/naturalcrit/homebrewery) -[![Patreon](/assets/patreon.png){height:30px}](https://patreon.com/NaturalCrit) -[![Reddit](/assets/reddit.png){height:30px}](https://www.reddit.com/r/homebrewery/) +[![Discord](https://homebrewery.naturalcrit.com/assets/discord.png){height:30px}](https://discord.gg/by3deKx) +[![Github](https://homebrewery.naturalcrit.com/assets/github.png){height:30px}](https://github.com/naturalcrit/homebrewery) +[![Patreon](https://homebrewery.naturalcrit.com/assets/patreon.png){height:30px}](https://patreon.com/NaturalCrit) +[![Reddit](https://homebrewery.naturalcrit.com/assets/reddit.png){height:30px}](https://www.reddit.com/r/homebrewery/) }} \page @@ -162,7 +162,7 @@ Images must be hosted online somewhere, like [Imgur](https://www.imgur.com). You Using *Curly Injection* you can assign an id, classes, or inline CSS properties to the Markdown image syntax. -![alt-text](https://s-media-cache-ak0.pinimg.com/736x/4a/81/79/4a8179462cfdf39054a418efd4cb743e.jpg) {width:100px,border:"2px solid",border-radius:10px} +![alt-text](https://homebrewery.naturalcrit.com/assets/catwarrior.jpg) {width:100px,border:"2px solid",border-radius:10px} \* *When using Imgur-hosted images, use the "direct link", which can be found when you click into your image in the Imgur interface.* diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 4e3084f57..16de1ba0e 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -4,29 +4,28 @@ import './newPage.less'; // Common imports import React, { useState, useEffect, useRef } from 'react'; import request from '../../utils/request-middleware.js'; -import Markdown from '../../../../shared/markdown.js'; +import Markdown from '@shared/markdown.js'; import _ from 'lodash'; import { DEFAULT_BREW } from '../../../../server/brewDefaults.js'; -import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '../../../../shared/helpers.js'; +import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '@shared/helpers.js'; import SplitPane from '../../../components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import NewBrewItem from '../../navbar/newbrew.navitem.jsx'; -import AccountNavItem from '../../navbar/account.navitem.jsx'; -import ErrorNavItem from '../../navbar/error-navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; -import VaultNavItem from '../../navbar/vault.navitem.jsx'; -import PrintNavItem from '../../navbar/print.navitem.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import NewBrewItem from '@navbar/newbrew.navitem.jsx'; +import AccountNavItem from '@navbar/account.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import VaultNavItem from '@navbar/vault.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; // Page specific imports -import { Meta } from 'vitreum/headtags'; const UNSAVED_WARNING_TIMEOUT = 9000; //Warn user afer 15 minutes of unsaved changes const UNSAVED_WARNING_POPUP_TIMEOUT = 4000; //Show the warning for 4 seconds @@ -64,7 +63,7 @@ const NewPage = (props)=>{ const lastSavedBrew = useRef(_.cloneDeep(props.brew)); // const saveTimeout = useRef(null); const warnUnsavedTimeout = useRef(null); - const trySaveRef = useRef(trySave); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew + const trySaveRef = useRef(null); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew const unsavedChangesRef = useRef(unsavedChanges); // Similarly, onBeforeUnload lives outside React and needs ref to unsavedChanges useEffect(()=>{ diff --git a/client/homebrew/pages/newPage/newPage.less b/client/homebrew/pages/newPage/newPage.less index d2f07ac40..39befb44e 100644 --- a/client/homebrew/pages/newPage/newPage.less +++ b/client/homebrew/pages/newPage/newPage.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/colors.less'; + .newPage { .navItem.save { background-color : @orange; diff --git a/client/homebrew/pages/sharePage/sharePage.jsx b/client/homebrew/pages/sharePage/sharePage.jsx index 4a0b0f99c..093fc8965 100644 --- a/client/homebrew/pages/sharePage/sharePage.jsx +++ b/client/homebrew/pages/sharePage/sharePage.jsx @@ -1,18 +1,19 @@ import './sharePage.less'; import React, { useState, useEffect, useCallback } from 'react'; -import { Meta } from 'vitreum/headtags'; +import Headtags from '../../../../vitreum/headtags.js'; +const Meta = Headtags.Meta; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import MetadataNav from '../../navbar/metadata.navitem.jsx'; -import PrintNavItem from '../../navbar/print.navitem.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import MetadataNav from '@navbar/metadata.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; -import Account from '../../navbar/account.navitem.jsx'; +import Account from '@navbar/account.navitem.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js'; -import { printCurrentBrew, fetchThemeBundle } from '../../../../shared/helpers.js'; +import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; const SharePage = (props)=>{ const { brew = DEFAULT_BREW_LOAD, disableMeta = false } = props; diff --git a/client/homebrew/pages/userPage/userPage.jsx b/client/homebrew/pages/userPage/userPage.jsx index a6a43858e..0b2ebb56b 100644 --- a/client/homebrew/pages/userPage/userPage.jsx +++ b/client/homebrew/pages/userPage/userPage.jsx @@ -3,15 +3,15 @@ import _ from 'lodash'; import ListPage from '../basePages/listPage/listPage.jsx'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; -import Account from '../../navbar/account.navitem.jsx'; -import NewBrew from '../../navbar/newbrew.navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; -import ErrorNavItem from '../../navbar/error-navitem.jsx'; -import VaultNavitem from '../../navbar/vault.navitem.jsx'; +import Account from '@navbar/account.navitem.jsx'; +import NewBrew from '@navbar/newbrew.navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import VaultNavitem from '@navbar/vault.navitem.jsx'; const UserPage = (props)=>{ props = { diff --git a/client/homebrew/pages/vaultPage/vaultPage.jsx b/client/homebrew/pages/vaultPage/vaultPage.jsx index 3a8c6bc25..e6a9768bb 100644 --- a/client/homebrew/pages/vaultPage/vaultPage.jsx +++ b/client/homebrew/pages/vaultPage/vaultPage.jsx @@ -3,13 +3,13 @@ import './vaultPage.less'; import React, { useState, useEffect, useRef } from 'react'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; -import Account from '../../navbar/account.navitem.jsx'; -import NewBrew from '../../navbar/newbrew.navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; +import Account from '@navbar/account.navitem.jsx'; +import NewBrew from '@navbar/newbrew.navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; import BrewItem from '../basePages/listPage/brewItem/brewItem.jsx'; import SplitPane from '../../../components/splitPane/splitPane.jsx'; import ErrorIndex from '../errorPage/errors/errorIndex.js'; diff --git a/client/homebrew/pages/vaultPage/vaultPage.less b/client/homebrew/pages/vaultPage/vaultPage.less index 304fefc72..b2010b59b 100644 --- a/client/homebrew/pages/vaultPage/vaultPage.less +++ b/client/homebrew/pages/vaultPage/vaultPage.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/core.less'; + .vaultPage { height : 100%; overflow-y : hidden; diff --git a/client/template.js b/client/template.js deleted file mode 100644 index 537be6748..000000000 --- a/client/template.js +++ /dev/null @@ -1,33 +0,0 @@ -const template = async function(name, title='', props = {}){ - const ogTags = []; - const ogMeta = props.ogMeta ?? {}; - Object.entries(ogMeta).forEach(([key, value])=>{ - if(!value) return; - const tag = ``; - ogTags.push(tag); - }); - const ogMetaTags = ogTags.join('\n'); - - const ssrModule = await import(`../build/${name}/ssr.cjs`); - - return ` - - - - - - - ${ogMetaTags} - - ${title.length ? `${title} - The Homebrewery`: 'The Homebrewery - NaturalCrit'} - - -
    ${ssrModule.default(props)}
    - - - - - `; -}; - -export default template; \ No newline at end of file diff --git a/themes/codeMirror/editorThemes.json b/editorThemes.json similarity index 100% rename from themes/codeMirror/editorThemes.json rename to editorThemes.json diff --git a/index.html b/index.html new file mode 100644 index 000000000..5ee864b28 --- /dev/null +++ b/index.html @@ -0,0 +1,29 @@ + + + + + + + + + + The Homebrewery - NaturalCrit + + + +
    + + + + diff --git a/package-lock.json b/package-lock.json index 06d4331b7..d3f4391a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,10 +14,11 @@ "@babel/plugin-transform-runtime": "^7.29.0", "@babel/preset-env": "^7.29.0", "@babel/preset-react": "^7.28.5", - "@babel/runtime": "^7.28.4", + "@babel/runtime": "^7.28.6", "@dmsnell/diff-match-patch": "^1.1.0", - "@googleapis/drive": "^19.2.0", + "@googleapis/drive": "^20.1.0", "@sanity/diff-match-patch": "^3.2.0", + "@vitejs/plugin-react": "^5.1.2", "body-parser": "^2.2.0", "classnames": "^2.5.1", "codemirror": "^5.65.6", @@ -26,7 +27,6 @@ "cors": "^2.8.5", "create-react-class": "^15.7.0", "dedent": "^1.7.1", - "expr-eval": "^2.0.2", "express": "^5.1.0", "express-async-handler": "^1.2.0", "express-static-gzip": "3.0.0", @@ -36,7 +36,7 @@ "idb-keyval": "^6.2.2", "js-yaml": "^4.1.1", "jwt-simple": "^0.5.6", - "less": "^3.13.1", + "less": "^4.5.1", "lodash": "^4.17.21", "marked": "15.0.12", "marked-alignment-paragraphs": "^1.0.0", @@ -50,21 +50,19 @@ "marked-variables": "^1.0.5", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^9.1.5", + "mongoose": "^9.2.1", "nanoid": "5.1.6", "nconf": "^0.13.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-frame-component": "^4.1.3", - "react-router": "^7.9.6", - "romans": "^3.1.0", + "node": "^25.7.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-frame-component": "^5.2.7", + "react-router": "^7.13.1", "sanitize-filename": "1.6.3", - "superagent": "^10.2.1", - "vitreum": "git+https://git@github.com/calculuschild/vitreum.git", - "written-number": "^0.11.1" + "superagent": "^10.2.1" }, "devDependencies": { - "@stylistic/stylelint-plugin": "^4.0.0", + "@stylistic/stylelint-plugin": "^5.0.1", "babel-jest": "^30.2.0", "babel-plugin-transform-import-meta": "^2.3.3", "eslint": "^9.39.1", @@ -73,13 +71,14 @@ "globals": "^16.4.0", "jest": "^30.2.0", "jest-expect-message": "^1.1.3", - "jsdom": "^28.0.0", + "jsdom": "^28.1.0", "jsdom-global": "^3.0.2", "postcss-less": "^6.0.0", - "stylelint": "^16.25.0", - "stylelint-config-recess-order": "^7.3.0", - "stylelint-config-recommended": "^17.0.0", - "supertest": "^7.1.4" + "stylelint": "^17.4.0", + "stylelint-config-recess-order": "^7.6.1", + "stylelint-config-recommended": "^18.0.0", + "supertest": "^7.1.4", + "vite": "^7.3.1" }, "engines": { "node": "^20.18.x", @@ -94,23 +93,26 @@ "license": "MIT" }, "node_modules/@asamuzakjp/css-color": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz", - "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.0.1.tgz", + "integrity": "sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-color-parser": "^3.1.0", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "lru-cache": "^11.2.4" + "@csstools/css-calc": "^3.1.1", + "@csstools/css-color-parser": "^4.0.2", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -118,9 +120,9 @@ } }, "node_modules/@asamuzakjp/dom-selector": { - "version": "6.7.7", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.7.tgz", - "integrity": "sha512-8CO/UQ4tzDd7ula+/CVimJIVWez99UJlbMyIgk8xOnhAVPKLnBZmUFYVgugS441v2ZqUq5EnSh6B0Ua0liSFAA==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", "dev": true, "license": "MIT", "dependencies": { @@ -128,13 +130,13 @@ "bidi-js": "^1.0.3", "css-tree": "^3.1.0", "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.2.5" + "lru-cache": "^11.2.6" } }, "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -203,9 +205,9 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.0.tgz", - "integrity": "sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.0", @@ -1517,6 +1519,36 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", @@ -1854,7 +1886,6 @@ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", @@ -1931,17 +1962,30 @@ "dev": true, "license": "MIT" }, - "node_modules/@cacheable/memory": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.7.tgz", - "integrity": "sha512-RbxnxAMf89Tp1dLhXMS7ceft/PGsDl1Ip7T20z5nZ+pwIAsQ1p2izPjVG69oCLv/jfQ7HDPHTWK0c9rcAWXN3A==", + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", "dev": true, "license": "MIT", "dependencies": { - "@cacheable/utils": "^2.3.3", - "@keyv/bigmap": "^1.3.0", - "hookified": "^1.14.0", - "keyv": "^5.5.5" + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@cacheable/memory": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.8.tgz", + "integrity": "sha512-FvEb29x5wVwu/Kf93IWwsOOEuhHh6dYCJF3vcKLzXc0KXIW181AOzv6ceT4ZpBHDvAfG60eqb+ekmrnLHIy+jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.4.0", + "@keyv/bigmap": "^1.3.1", + "hookified": "^1.15.1", + "keyv": "^5.6.0" } }, "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": { @@ -1973,14 +2017,14 @@ } }, "node_modules/@cacheable/utils": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.3.3.tgz", - "integrity": "sha512-JsXDL70gQ+1Vc2W/KUFfkAJzgb4puKwwKehNLuB+HrNKWf91O736kGfxn4KujXCCSuh6mRRL4XEB0PkAFjWS0A==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.4.0.tgz", + "integrity": "sha512-PeMMsqjVq+bF0WBsxFBxr/WozBJiZKY0rUojuaCoIaKnEl3Ju1wfEwS+SV1DU/cSe8fqHIPiYJFif8T3MVt4cQ==", "dev": true, "license": "MIT", "dependencies": { - "hashery": "^1.3.0", - "keyv": "^5.5.5" + "hashery": "^1.5.0", + "keyv": "^5.6.0" } }, "node_modules/@cacheable/utils/node_modules/keyv": { @@ -1994,9 +2038,9 @@ } }, "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", "dev": true, "funding": [ { @@ -2010,13 +2054,13 @@ ], "license": "MIT-0", "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", + "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", "dev": true, "funding": [ { @@ -2030,17 +2074,17 @@ ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz", + "integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==", "dev": true, "funding": [ { @@ -2054,21 +2098,21 @@ ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.1.1" }, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", "dev": true, "funding": [ { @@ -2083,16 +2127,16 @@ "license": "MIT", "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.26.tgz", - "integrity": "sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==", + "version": "1.0.29", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.29.tgz", + "integrity": "sha512-jx9GjkkP5YHuTmko2eWAvpPnb0mB4mGRr2U7XwVNwevm8nlpobZEVk+GNmiYMk2VuA75v+plfXWyroWKmICZXg==", "dev": true, "funding": [ { @@ -2107,9 +2151,9 @@ "license": "MIT-0" }, "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", "dev": true, "funding": [ { @@ -2124,13 +2168,13 @@ "license": "MIT", "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, "node_modules/@csstools/media-query-list-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", - "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-5.0.0.tgz", + "integrity": "sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==", "dev": true, "funding": [ { @@ -2144,17 +2188,17 @@ ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, - "node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "node_modules/@csstools/selector-resolve-nested": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-4.0.0.tgz", + "integrity": "sha512-9vAPxmp+Dx3wQBIUwc1v7Mdisw1kbbaGqXUM8QLTgWg7SoPGYtXBsMXvsFs/0Bn5yoFhcktzxNZGNaUt0VjgjA==", "dev": true, "funding": [ { @@ -2168,10 +2212,33 @@ ], "license": "MIT-0", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "postcss-selector-parser": "^7.0.0" + "postcss-selector-parser": "^7.1.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.0.tgz", + "integrity": "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.1.1" } }, "node_modules/@dmsnell/diff-match-patch": { @@ -2180,17 +2247,6 @@ "integrity": "sha512-yejLPmM5pjsGvxS9gXablUSbInW7H976c/FJ4iQxWIm7/38xBySRemTPDe34lhg1gVLbJntX0+sH0jYfU+PN9A==", "license": "Apache-2.0" }, - "node_modules/@dual-bundle/import-meta-resolve": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.2.1.tgz", - "integrity": "sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/JounQin" - } - }, "node_modules/@emnapi/core": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", @@ -2225,6 +2281,422 @@ "tslib": "^2.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", @@ -2309,20 +2781,20 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz", + "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", + "minimatch": "^3.1.3", "strip-json-comments": "^3.1.1" }, "engines": { @@ -2346,9 +2818,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "version": "9.39.3", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.3.tgz", + "integrity": "sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==", "dev": true, "license": "MIT", "engines": { @@ -2383,9 +2855,9 @@ } }, "node_modules/@exodus/bytes": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.11.0.tgz", - "integrity": "sha512-wO3vd8nsEHdumsXrjGO/v4p6irbg7hy9kvIeR6i2AwylZSk4HJdWgL0FNaVquW1+AweJcdvU1IEpuIWk/WaPnA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.14.1.tgz", + "integrity": "sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ==", "dev": true, "license": "MIT", "engines": { @@ -2401,9 +2873,9 @@ } }, "node_modules/@googleapis/drive": { - "version": "19.2.1", - "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-19.2.1.tgz", - "integrity": "sha512-BM2r8B9dTo1zdi+fEPa62GgVjwP2EfaYoD1rTLYlA0SoWhNsaX/PKLBLEjEwkxZuIIQ12y57HZQjti6Jgudwtg==", + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-20.1.0.tgz", + "integrity": "sha512-8/gapeLuZ3igooEGLE1AL3Zp5fjqigZQNmyjehb4QF7JVJh6FXF+72AcQGGsFypwJb2S68HIuQFomHBw4RJSOg==", "license": "Apache-2.0", "dependencies": { "googleapis-common": "^8.0.0" @@ -2927,9 +3399,9 @@ "license": "MIT" }, "node_modules/@mongodb-js/saslprep": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.5.tgz", - "integrity": "sha512-k64Lbyb7ycCSXHSLzxVdb2xsKGPMvYZfCICXvDsI8Z65CeWQzTEKS4YmGbnqw+U9RBvLPTsB6UCmwkgsDTGWIw==", + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz", + "integrity": "sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==", "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" @@ -3031,6 +3503,337 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sanity/diff-match-patch": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@sanity/diff-match-patch/-/diff-match-patch-3.2.0.tgz", @@ -3047,6 +3850,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -3068,25 +3884,25 @@ } }, "node_modules/@stylistic/stylelint-plugin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-4.0.1.tgz", - "integrity": "sha512-jKZSZr/S/NehfgayNJI3O/JEq+W5lSeHUJNvdOebRPNFP2ZylTbAx/p5qR8scQFpiVzy1VQM9R+G0kIB62r1Pw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-5.0.1.tgz", + "integrity": "sha512-NaVwCNVZ2LyPA3TnUwvjO9c6P6VUjgRB8UP8SOW+cAOJBVqPPuOIDawsvvtql/LhkuR3JuTdGvr/RM3dUl8l2Q==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "@csstools/media-query-list-parser": "^5.0.0", "postcss": "^8.5.6", - "postcss-selector-parser": "^7.1.0", + "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0", "style-search": "^0.1.0" }, "engines": { - "node": "^18.12 || >=20.9" + "node": ">=20.19.0" }, "peerDependencies": { - "stylelint": "^16.22.0" + "stylelint": "^17.0.0" } }, "node_modules/@tybys/wasm-util": { @@ -3104,7 +3920,6 @@ "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", @@ -3118,7 +3933,6 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" @@ -3128,7 +3942,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", @@ -3139,7 +3952,6 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.28.2" @@ -3149,7 +3961,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, "license": "MIT" }, "node_modules/@types/istanbul-lib-coverage": { @@ -3187,13 +3998,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", - "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", - "dev": true, + "version": "25.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", + "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", + "devOptional": true, "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/stack-utils": { @@ -3236,14 +4047,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/project-service": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", - "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.54.0", - "@typescript-eslint/types": "^8.54.0", + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "engines": { @@ -3258,14 +4069,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", - "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3276,9 +4087,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", - "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", "dev": true, "license": "MIT", "engines": { @@ -3293,9 +4104,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", - "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, "license": "MIT", "engines": { @@ -3307,18 +4118,18 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", - "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.54.0", - "@typescript-eslint/tsconfig-utils": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -3334,36 +4145,49 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -3374,16 +4198,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", - "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3393,19 +4217,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", - "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3415,6 +4239,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", @@ -3691,6 +4528,26 @@ "win32" ] }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", + "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -3705,9 +4562,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "peer": true, @@ -3728,38 +4585,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "license": "Apache-2.0", - "dependencies": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - } - }, - "node_modules/acorn-node/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -3770,9 +4595,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -3833,6 +4658,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -3848,33 +4674,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", @@ -3915,25 +4714,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array.prototype.findlast": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", @@ -4038,42 +4818,6 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, - "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, - "node_modules/assert": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz", - "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==", - "license": "MIT", - "dependencies": { - "object.assign": "^4.1.4", - "util": "^0.10.4" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -4090,18 +4834,6 @@ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, - "node_modules/async-each": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", - "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT" - }, "node_modules/async-function": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", @@ -4118,31 +4850,11 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -4312,49 +5024,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "license": "MIT", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -4376,12 +5045,15 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/bidi-js": { @@ -4403,34 +5075,6 @@ "node": "*" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bn.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", - "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", - "license": "MIT" - }, "node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", @@ -4459,6 +5103,7 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -4469,6 +5114,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -4477,227 +5123,6 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "license": "MIT" - }, - "node_modules/browser-pack": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", - "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", - "license": "MIT", - "dependencies": { - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "JSONStream": "^1.0.3", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" - }, - "bin": { - "browser-pack": "bin/cmd.js" - } - }, - "node_modules/browser-pack/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", - "license": "MIT", - "dependencies": { - "resolve": "^1.17.0" - } - }, - "node_modules/browserify": { - "version": "16.5.2", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.2.tgz", - "integrity": "sha512-TkOR1cQGdmXU9zW4YukWzWVSJwrxmNdADFbqbE3HFgQWe5wqZmOawqZ7J/8MPCwk/W8yY7Y0h+7mOtcZxLP23g==", - "license": "MIT", - "dependencies": { - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^2.0.0", - "browserify-zlib": "~0.2.0", - "buffer": "~5.2.1", - "cached-path-relative": "^1.0.0", - "concat-stream": "^1.6.0", - "console-browserify": "^1.1.0", - "constants-browserify": "~1.0.0", - "crypto-browserify": "^3.0.0", - "defined": "^1.0.0", - "deps-sort": "^2.0.0", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^2.0.0", - "glob": "^7.1.0", - "has": "^1.0.0", - "htmlescape": "^1.1.0", - "https-browserify": "^1.0.0", - "inherits": "~2.0.1", - "insert-module-globals": "^7.0.0", - "JSONStream": "^1.0.3", - "labeled-stream-splicer": "^2.0.0", - "mkdirp-classic": "^0.5.2", - "module-deps": "^6.2.3", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "~0.0.0", - "process": "~0.11.0", - "punycode": "^1.3.2", - "querystring-es3": "~0.2.0", - "read-only-stream": "^2.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.4", - "shasum": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^2.0.0", - "stream-http": "^3.0.0", - "string_decoder": "^1.1.1", - "subarg": "^1.0.0", - "syntax-error": "^1.1.1", - "through2": "^2.0.0", - "timers-browserify": "^1.0.1", - "tty-browserify": "0.0.1", - "url": "~0.11.0", - "util": "~0.10.1", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" - }, - "bin": { - "browserify": "bin/cmd.js" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "license": "MIT", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "license": "MIT", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", - "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^5.2.1", - "randombytes": "^2.1.0", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.5.tgz", - "integrity": "sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==", - "license": "ISC", - "dependencies": { - "bn.js": "^5.2.2", - "browserify-rsa": "^4.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.6.1", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.9", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "license": "MIT", - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserify/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/browserify/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "license": "MIT" - }, - "node_modules/browserify/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "node_modules/browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", @@ -4751,16 +5176,6 @@ "node": ">=20.19.0" } }, - "node_modules/buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "license": "MIT", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -4771,18 +5186,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "license": "MIT" - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true, "license": "MIT" }, "node_modules/bytes": { @@ -4794,37 +5198,17 @@ "node": ">= 0.8" } }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "license": "MIT", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cacheable": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.2.tgz", - "integrity": "sha512-w+ZuRNmex9c1TR9RcsxbfTKCjSL0rh1WA5SABbrWprIHeNBdmyQLSYonlDy9gpD+63XT8DgZ/wNh1Smvc9WnJA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.3.tgz", + "integrity": "sha512-iffYMX4zxKp54evOH27fm92hs+DeC1DhXmNVN8Tr94M/iZIV42dqTHSR2Ik4TOSPyOAwKr7Yu3rN9ALoLkbWyQ==", "dev": true, "license": "MIT", "dependencies": { - "@cacheable/memory": "^2.0.7", - "@cacheable/utils": "^2.3.3", + "@cacheable/memory": "^2.0.8", + "@cacheable/utils": "^2.4.0", "hookified": "^1.15.0", - "keyv": "^5.5.5", + "keyv": "^5.6.0", "qified": "^0.6.0" } }, @@ -4838,16 +5222,11 @@ "@keyv/serialize": "^1.1.1" } }, - "node_modules/cached-path-relative": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", - "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", - "license": "MIT" - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", @@ -4912,9 +5291,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001767", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001767.tgz", - "integrity": "sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==", + "version": "1.0.30001776", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001776.tgz", + "integrity": "sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw==", "funding": [ { "type": "opencollective", @@ -4958,42 +5337,6 @@ "node": ">=10" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/ci-info": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", @@ -5010,20 +5353,6 @@ "node": ">=8" } }, - "node_modules/cipher-base": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", - "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.2" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/cjs-module-lexer": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", @@ -5031,21 +5360,6 @@ "dev": true, "license": "MIT" }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", @@ -5142,9 +5456,9 @@ } }, "node_modules/codemirror": { - "version": "5.65.20", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.20.tgz", - "integrity": "sha512-i5dLDDxwkFCbhjvL2pNjShsojoL3XHyDwsGv1jqETUoW+lzpBKKqNTUWgQwVAOa0tUm4BwekT455ujafi8payA==", + "version": "5.65.21", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.21.tgz", + "integrity": "sha512-6teYk0bA0nR3QP0ihGMoxuKzpl5W80FpnHpBJpgy66NK3cZv5b/d/HY8PnRvfSsCG1MTfr92u2WUl+wT0E40mQ==", "license": "MIT" }, "node_modules/collect-v8-coverage": { @@ -5154,19 +5468,6 @@ "dev": true, "license": "MIT" }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "license": "MIT", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -5192,33 +5493,6 @@ "dev": true, "license": "MIT" }, - "node_modules/combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", - "license": "MIT", - "dependencies": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - } - }, - "node_modules/combine-source-map/node_modules/convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", - "license": "MIT" - }, - "node_modules/combine-source-map/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5244,32 +5518,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true, "license": "MIT" }, "node_modules/content-disposition": { @@ -5346,15 +5595,6 @@ "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/core-js": { "version": "3.48.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz", @@ -5379,12 +5619,6 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, "node_modules/cors": { "version": "2.8.6", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", @@ -5403,9 +5637,9 @@ } }, "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5429,49 +5663,6 @@ } } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "node_modules/create-react-class": { "version": "15.7.0", "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz", @@ -5496,40 +5687,14 @@ "node": ">= 8" } }, - "node_modules/crypto-browserify": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz", - "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==", - "license": "MIT", - "dependencies": { - "browserify-cipher": "^1.0.1", - "browserify-sign": "^4.2.3", - "create-ecdh": "^4.0.4", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "diffie-hellman": "^5.0.3", - "hash-base": "~3.0.4", - "inherits": "^2.0.4", - "pbkdf2": "^3.1.2", - "public-encrypt": "^4.0.3", - "randombytes": "^2.1.0", - "randomfill": "^1.0.4" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/css-functions-list": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", - "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.3.3.tgz", + "integrity": "sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==", "dev": true, "license": "MIT", "engines": { - "node": ">=12 || >=16" + "node": ">=12" } }, "node_modules/css-tree": { @@ -5560,37 +5725,31 @@ } }, "node_modules/cssstyle": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", - "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.2.0.tgz", + "integrity": "sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^4.1.1", - "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "@asamuzakjp/css-color": "^5.0.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.28", "css-tree": "^3.1.0", - "lru-cache": "^11.2.4" + "lru-cache": "^11.2.6" }, "engines": { "node": ">=20" } }, "node_modules/cssstyle/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, - "node_modules/dash-ast": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", - "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", - "license": "Apache-2.0" - }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -5692,19 +5851,10 @@ "dev": true, "license": "MIT" }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/dedent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", - "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -5736,6 +5886,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -5753,6 +5904,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", @@ -5766,27 +5918,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defined": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5805,41 +5936,6 @@ "node": ">= 0.8" } }, - "node_modules/deps-sort": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", - "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", - "license": "MIT", - "dependencies": { - "JSONStream": "^1.0.3", - "shasum-object": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" - }, - "bin": { - "deps-sort": "bin/cmd.js" - } - }, - "node_modules/deps-sort/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -5850,23 +5946,6 @@ "node": ">=8" } }, - "node_modules/detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", - "license": "MIT", - "dependencies": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - }, - "bin": { - "detective": "bin/detective.js" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/dezalgo": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", @@ -5877,36 +5956,6 @@ "wrappy": "1" } }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -5920,16 +5969,6 @@ "node": ">=0.10.0" } }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "license": "MIT", - "engines": { - "node": ">=0.4", - "npm": ">=1.2" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -5944,15 +5983,6 @@ "node": ">= 0.4" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "license": "BSD-3-Clause", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -5975,32 +6005,11 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.286", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", - "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", + "version": "1.5.307", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", + "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==", "license": "ISC" }, - "node_modules/elliptic": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", - "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", @@ -6248,6 +6257,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -6277,9 +6327,9 @@ } }, "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "9.39.3", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.3.tgz", + "integrity": "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==", "dev": true, "license": "MIT", "peer": true, @@ -6290,7 +6340,7 @@ "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", + "@eslint/js": "9.39.3", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -6338,9 +6388,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "29.12.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.12.2.tgz", - "integrity": "sha512-IIRg0IZ5yuERfzOZrKuNScxk9yeuKo0M4Urx7RZcthK5HE/8gJUY518bdi7picLRBJVctjOW3yVx0zyBp4Cq+g==", + "version": "29.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.0.tgz", + "integrity": "sha512-ZCGr7vTH2WSo2hrK5oM2RULFmMruQ7W3cX7YfwoTiPfzTGTFBMmrVIz45jZHd++cGKj/kWf02li/RhTGcANJSA==", "dev": true, "license": "MIT", "dependencies": { @@ -6351,7 +6401,7 @@ }, "peerDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "jest": "*", "typescript": ">=4.8.4 <6.0.0" }, @@ -6401,19 +6451,25 @@ } }, "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6583,25 +6639,6 @@ "node": ">= 0.6" } }, - "node_modules/events": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", - "license": "MIT", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "license": "MIT", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -6643,39 +6680,6 @@ "node": ">= 0.8.0" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "license": "MIT", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, "node_modules/expect": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", @@ -6775,62 +6779,6 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "license": "MIT", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -6977,17 +6925,11 @@ "node": ">=16.0.0" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT", - "optional": true - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -7046,9 +6988,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.4.tgz", + "integrity": "sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==", "dev": true, "license": "ISC" }, @@ -7056,6 +6998,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.2.7" @@ -7067,15 +7010,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -7167,18 +7101,6 @@ "node": ">= 0.6" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "license": "MIT", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", @@ -7189,9 +7111,9 @@ } }, "node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -7206,6 +7128,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -7263,15 +7186,14 @@ } }, "node_modules/gaxios": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", - "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", + "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2", - "rimraf": "^5.0.1" + "node-fetch": "^3.3.2" }, "engines": { "node": ">=18" @@ -7310,12 +7232,6 @@ "node": ">=6.9.0" } }, - "node_modules/get-assigned-identifiers": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", - "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", - "license": "Apache-2.0" - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -7325,6 +7241,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -7403,15 +7332,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/github-slugger": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", @@ -7462,12 +7382,12 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -7555,21 +7475,44 @@ } }, "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-16.1.1.tgz", + "integrity": "sha512-dW7vl+yiAJSp6aCekaVnVJxurRv7DCOLyXqEG3RYMYUg7AuJ2jCqPkZTA8ooqC2vtnkaMcV5WfFBMuEnTu1OQg==", "dev": true, "license": "MIT", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "@sindresorhus/merge-streams": "^4.0.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.5", + "is-path-inside": "^4.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.4.0" }, "engines": { - "node": ">=10" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -7583,23 +7526,37 @@ "license": "MIT" }, "node_modules/google-auth-library": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", - "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.1.tgz", + "integrity": "sha512-5awwuLrzNol+pFDmKJd0dKtZ0fPLAtoA5p7YO4ODsDu6ONJUVqbYwvv8y2ZBO5MBNp9TJXigB19710kYpBPdtA==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^7.0.0", - "gcp-metadata": "^8.0.0", - "google-logging-utils": "^1.0.0", - "gtoken": "^8.0.0", + "gaxios": "7.1.3", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", "jws": "^4.0.0" }, "engines": { "node": ">=18" } }, + "node_modules/google-auth-library/node_modules/gaxios": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/google-logging-utils": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", @@ -7643,28 +7600,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/gtoken": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", - "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", - "license": "MIT", - "dependencies": { - "gaxios": "^7.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -7692,6 +7627,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -7743,102 +7679,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "license": "MIT", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hash-base": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz", - "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/hash-wasm": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.12.0.tgz", "integrity": "sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ==", "license": "MIT" }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "node_modules/hashery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.4.0.tgz", - "integrity": "sha512-Wn2i1In6XFxl8Az55kkgnFRiAlIAushzh26PTjL2AKtQcEfXrcLa7Hn5QOWGZEf3LU057P9TwwZjFyxfS1VuvQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.0.tgz", + "integrity": "sha512-nhQ6ExaOIqti2FDWoEMWARUqIKyjr2VcZzXShrI+A3zpeiuPWzx6iPftt44LhP74E5sW36B75N6VHbvRtpvO6Q==", "dev": true, "license": "MIT", "dependencies": { @@ -7860,17 +7710,6 @@ "node": ">= 0.4" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/hookified": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", @@ -7899,27 +7738,18 @@ "license": "MIT" }, "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-5.1.0.tgz", + "integrity": "sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=20.10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -7954,12 +7784,6 @@ "node": ">= 14" } }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "license": "MIT" - }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -8005,26 +7829,6 @@ "integrity": "sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==", "license": "Apache-2.0" }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -8035,12 +7839,6 @@ "node": ">= 4" } }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "license": "ISC" - }, "node_modules/image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", @@ -8101,6 +7899,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -8116,6 +7925,7 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -8137,55 +7947,6 @@ "node": ">=10" } }, - "node_modules/inline-source-map": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.3.tgz", - "integrity": "sha512-1aVsPEsJWMJq/pdMU61CDlm1URcW702MTB4w9/zUjMus6H/Py8o7g68Pr9D4I6QluWGt/KdmswuRhaA05xVR1w==", - "license": "MIT", - "dependencies": { - "source-map": "~0.5.3" - } - }, - "node_modules/inline-source-map/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/insert-module-globals": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", - "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", - "license": "MIT", - "dependencies": { - "acorn-node": "^1.5.2", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "JSONStream": "^1.0.3", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "undeclared-identifiers": "^1.1.2", - "xtend": "^4.0.0" - }, - "bin": { - "insert-module-globals": "bin/cmd.js" - } - }, - "node_modules/insert-module-globals/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -8210,18 +7971,6 @@ "node": ">= 0.10" } }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", - "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -8283,18 +8032,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-boolean-object": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", @@ -8312,16 +8049,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "license": "MIT" - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8345,18 +8077,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", - "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/is-data-view": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", @@ -8392,32 +8112,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8482,6 +8181,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -8520,6 +8220,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -8542,6 +8243,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -8665,6 +8379,7 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" @@ -8728,19 +8443,11 @@ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", "license": "MIT" }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, "license": "MIT" }, "node_modules/isexe": { @@ -8749,15 +8456,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -8786,9 +8484,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -9362,9 +9060,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -9508,17 +9206,18 @@ } }, "node_modules/jsdom": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.0.0.tgz", - "integrity": "sha512-KDYJgZ6T2TKdU8yBfYueq5EPG/EylMsBvCaenWMJb2OXmjgczzwveRCoJ+Hgj1lXPDyasvrgneSn4GBuR1hYyA==", + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.1.0.tgz", + "integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@acemir/cssom": "^0.9.31", - "@asamuzakjp/dom-selector": "^6.7.6", + "@asamuzakjp/dom-selector": "^6.8.1", + "@bramus/specificity": "^2.4.2", "@exodus/bytes": "^1.11.0", - "cssstyle": "^5.3.7", + "cssstyle": "^6.0.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", @@ -9529,7 +9228,7 @@ "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.0", - "undici": "^7.20.0", + "undici": "^7.21.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", @@ -9600,15 +9299,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-stable-stringify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", - "integrity": "sha512-nKtD/Qxm7tWdZqJoldEC7fF0S41v0mWbeaXG3637stOWfyGxTgWTYE2wtfKmjzpvxv2MA2xzxsXOIiwUpkX6Qw==", - "license": "MIT", - "dependencies": { - "jsonify": "~0.0.0" - } - }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -9640,40 +9330,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", - "license": "Public Domain", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -9721,9 +9377,9 @@ } }, "node_modules/kareem": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-3.0.0.tgz", - "integrity": "sha512-RKhaOBSPN8L7y4yAgNhDT2602G5FD6QbOIISbjN9D6mjHPeqeg7K+EB5IGSU5o81/X2Gzm3ICnAvQW3x3OP8HA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-3.2.0.tgz", + "integrity": "sha512-VS8MWZz/cT+SqBCpVfNN4zoVz5VskR3N4+sTmUXme55e9avQHntpwpNq0yjnosISXqwJ3AQVjlbI4Dyzv//JtA==", "license": "Apache-2.0", "engines": { "node": ">=18.0.0" @@ -9743,42 +9399,28 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/known-css-properties": { - "version": "0.37.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", - "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/labeled-stream-splicer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", - "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "stream-splicer": "^2.0.0" - } - }, "node_modules/less": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz", - "integrity": "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/less/-/less-4.5.1.tgz", + "integrity": "sha512-UKgI3/KON4u6ngSsnDADsUERqhZknsVZbnuzlRZXLQCmfC/MDld42fTydUE9B+Mla1AL6SJ/Pp6SlEFi/AVGfw==", + "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "copy-anything": "^2.0.1", - "tslib": "^1.10.0" + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" }, "bin": { "lessc": "bin/lessc" }, "engines": { - "node": ">=6" + "node": ">=14" }, "optionalDependencies": { "errno": "^0.1.1", @@ -9786,7 +9428,7 @@ "image-size": "~0.5.0", "make-dir": "^2.1.0", "mime": "^1.4.1", - "native-request": "^1.0.5", + "needle": "^3.1.0", "source-map": "~0.6.0" } }, @@ -9814,12 +9456,6 @@ "semver": "bin/semver" } }, - "node_modules/less/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "license": "0BSD" - }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -9851,30 +9487,6 @@ "dev": true, "license": "MIT" }, - "node_modules/livereload": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", - "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.0", - "livereload-js": "^3.3.1", - "opts": ">= 1.2.0", - "ws": "^7.4.3" - }, - "bin": { - "livereload": "bin/livereload.js" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/livereload-js": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.4.1.tgz", - "integrity": "sha512-5MP0uUeVCec89ZbNOT/i97Mc+q3SxXmiUGhRFOTmhrGPn//uWVQdCvcLJDy64MSBR5MidFdOR7B9viumoavy6g==", - "license": "MIT" - }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -9900,12 +9512,6 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "license": "MIT" }, - "node_modules/lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -9958,9 +9564,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -9980,27 +9586,6 @@ "tmpl": "1.0.5" } }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "license": "MIT", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/marked": { "version": "15.0.12", "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", @@ -10126,9 +9711,9 @@ } }, "node_modules/mathml-tag-names": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-4.0.0.tgz", + "integrity": "sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==", "dev": true, "license": "MIT", "funding": { @@ -10136,17 +9721,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "node_modules/mdn-data": { "version": "2.12.2", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", @@ -10170,13 +9744,13 @@ "license": "MIT" }, "node_modules/meow": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-14.1.0.tgz", + "integrity": "sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -10234,25 +9808,6 @@ "node": ">=8.6" } }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -10301,22 +9856,11 @@ "node": ">=6" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "license": "ISC" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "license": "MIT" - }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -10325,106 +9869,15 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "license": "MIT", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT" - }, - "node_modules/module-deps": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", - "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", - "license": "MIT", - "dependencies": { - "browser-resolve": "^2.0.0", - "cached-path-relative": "^1.0.2", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.2.0", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "JSONStream": "^1.0.3", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.4.0", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "bin": { - "module-deps": "bin/cmd.js" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/module-deps/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -10482,12 +9935,12 @@ } }, "node_modules/mongoose": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.1.5.tgz", - "integrity": "sha512-N6gypEO+wLmZp8kCYNQmrEWxVMT0KhyHvVttBZoKA/1ngY7aUsBjqHzCPtDgz+i8JAnqMOiEKmuJIDEQu1b9Dw==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.2.3.tgz", + "integrity": "sha512-4XFKKkXUOsdY+p07eJyio4mk0rzZOT4n5r5tLqZNeRZ/IsS68vS8Szw8uShX4p7S687XGGc+MFAp+6K1OIN0aw==", "license": "MIT", "dependencies": { - "kareem": "3.0.0", + "kareem": "3.2.0", "mongodb": "~7.0", "mpath": "0.9.0", "mquery": "6.0.0", @@ -10588,13 +10041,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/nan": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.25.0.tgz", - "integrity": "sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==", - "license": "MIT", - "optional": true - }, "node_modules/nanoid": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz", @@ -10613,91 +10059,6 @@ "node": "^18 || >=20" } }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/napi-postinstall": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", @@ -10714,13 +10075,6 @@ "url": "https://opencollective.com/napi-postinstall" } }, - "node_modules/native-request": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.2.tgz", - "integrity": "sha512-/etjwrK0J4Ebbcnt35VMWnfiUX/B04uwGJxyJInagxDqf2z5drSt/lsOvEMWGYunz1kaLZAFrV4NDAbOoDKvAQ==", - "license": "MIT", - "optional": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -10839,6 +10193,36 @@ "node": ">=10" } }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", @@ -10848,6 +10232,28 @@ "node": ">= 0.6" } }, + "node_modules/node": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/node/-/node-25.7.0.tgz", + "integrity": "sha512-C4iA3H4ldvQc8P6o0lCik0PCHimX5Yd+qknA/GmgmW2EsNkWek+8YQ0IEqi8vutuk+JNa4Pit94bMTzpSeA5Vg==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-bin-setup": "^1.0.0" + }, + "bin": { + "node": "bin/node" + }, + "engines": { + "npm": ">=5.0.0" + } + }, + "node_modules/node-bin-setup": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.1.4.tgz", + "integrity": "sha512-vWNHOne0ZUavArqPP5LJta50+S8R261Fr5SvGul37HbEDcowvLjwdvd0ZeSr0r2lTSrPxl6okq9QUw8BFGiAxA==", + "license": "ISC" + }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -10868,6 +10274,25 @@ "node": ">=10.5.0" } }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/node-fetch": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", @@ -10899,77 +10324,11 @@ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "license": "MIT" }, - "node_modules/nodemon": { - "version": "2.0.22", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", - "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10997,32 +10356,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "license": "MIT", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -11039,27 +10372,17 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.assign": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -11111,18 +10434,6 @@ "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", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.values": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", @@ -11197,27 +10508,6 @@ "node": ">= 0.8.0" } }, - "node_modules/opts": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", - "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", - "license": "BSD-2-Clause" - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "license": "MIT" - }, - "node_modules/outpipe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz", - "integrity": "sha512-BnNY/RwnDrkmQdUa9U+OfN/Y7AWmKuUPCCd+hbRclZnnANvYpO72zp/a6Q4n829hPbdqEac31XCcsvlEvb+rtA==", - "license": "MIT", - "dependencies": { - "shell-quote": "^1.4.2" - } - }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -11297,12 +10587,6 @@ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "license": "(MIT AND Zlib)" - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -11316,31 +10600,6 @@ "node": ">=6" } }, - "node_modules/parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", - "license": "MIT", - "dependencies": { - "path-platform": "~0.11.15" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.9.tgz", - "integrity": "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==", - "license": "ISC", - "dependencies": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "pbkdf2": "^3.1.5", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -11360,6 +10619,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/parse5": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", @@ -11382,27 +10650,6 @@ "node": ">= 0.8" } }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "license": "MIT" - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "license": "MIT" - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -11417,6 +10664,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11437,15 +10685,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, - "node_modules/path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -11478,33 +10717,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz", - "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==", - "license": "MIT", - "dependencies": { - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "ripemd160": "^2.0.3", - "safe-buffer": "^5.2.1", - "sha.js": "^2.4.12", - "to-buffer": "^1.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -11515,6 +10727,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -11556,29 +10769,20 @@ "node": ">=8" } }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "funding": [ { "type": "opencollective", @@ -11617,13 +10821,6 @@ "postcss": "^8.3.5" } }, - "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", - "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", - "dev": true, - "license": "MIT" - }, "node_modules/postcss-safe-parser": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", @@ -11687,7 +10884,6 @@ "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, "funding": [ { "type": "github", @@ -11740,21 +10936,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT" - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -11793,32 +10974,6 @@ "license": "MIT", "optional": true }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "license": "MIT" - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -11859,9 +11014,9 @@ } }, "node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -11873,14 +11028,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -11902,25 +11049,6 @@ ], "license": "MIT" }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "license": "MIT", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -11946,36 +11074,32 @@ } }, "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", "peer": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", "peer": true, "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^18.3.1" + "react": "^19.2.4" } }, "node_modules/react-frame-component": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-4.1.3.tgz", - "integrity": "sha512-4PurhctiqnmC1F5prPZ+LdsalH7pZ3SFA5xoc0HBe8mSHctdLLt4Cr2WXfXOoajHBYq/yiipp9zOgx+vy8GiEA==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-5.2.7.tgz", + "integrity": "sha512-ROjHtSLoSVYUBfTieazj/nL8jIX9rZFmHC0yXEU+dx6Y82OcBEGgU9o7VyHMrBFUN9FuQ849MtIPNNLsb4krbg==", "license": "MIT", "peerDependencies": { "prop-types": "^15.5.9", @@ -11990,10 +11114,19 @@ "dev": true, "license": "MIT" }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-router": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz", - "integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==", + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz", + "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -12025,63 +11158,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/read-only-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==", - "license": "MIT", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/readable-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -12123,56 +11199,6 @@ "node": ">=4" } }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", @@ -12229,30 +11255,6 @@ "regjsparser": "bin/parser" } }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "license": "ISC" - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -12315,22 +11317,6 @@ "node": ">=8" } }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "license": "MIT" - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "license": "MIT", - "engines": { - "node": ">=0.12" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -12357,32 +11343,48 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ripemd160": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", - "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "license": "MIT", "dependencies": { - "hash-base": "^3.1.2", - "inherits": "^2.0.4" + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ripemd160/node_modules/hash-base": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", - "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.1" + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "engines": { - "node": ">= 0.8" + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" } }, "node_modules/romans": { @@ -12488,15 +11490,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "license": "MIT", - "dependencies": { - "ret": "~0.1.10" - } - }, "node_modules/safe-regex-test": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", @@ -12530,6 +11523,16 @@ "truncate-utf8-bytes": "^1.0.0" } }, + "node_modules/sax": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "license": "BlueOak-1.0.0", + "optional": true, + "engines": { + "node": ">=11.0.0" + } + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -12544,13 +11547,10 @@ } }, "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" }, "node_modules/secure-keys": { "version": "1.0.0", @@ -12622,6 +11622,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -12666,81 +11667,12 @@ "node": ">= 0.4" } }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, - "node_modules/sha.js": { - "version": "2.4.12", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", - "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.0" - }, - "bin": { - "sha.js": "bin.js" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/shasum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", - "integrity": "sha512-UTzHm/+AzKfO9RgPgRpDIuMSNie1ubXRaljjlhFMNGYoG7z+rm9AHLPMf70R7887xboDH9Q+5YQbWKObFHEAtw==", - "license": "MIT", - "dependencies": { - "json-stable-stringify": "~0.0.0", - "sha.js": "~2.4.4" - } - }, - "node_modules/shasum-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.1.tgz", - "integrity": "sha512-SsC+1tW7XKQ/94D4k1JhLmjDFpVGET/Nf54jVDtbavbALf8Zhp0Td9zTlxScjMW6nbEIrpADtPWfLk9iCXzHDQ==", - "license": "Apache-2.0", - "dependencies": { - "fast-safe-stringify": "^2.0.7" - }, - "bin": { - "shasum-object": "bin.js" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12762,18 +11694,6 @@ "node": ">=8" } }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -12864,47 +11784,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-update-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", - "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", - "license": "MIT", - "dependencies": { - "semver": "~7.0.0" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -12933,116 +11812,11 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "license": "MIT", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "license": "MIT", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "license": "MIT", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -13052,26 +11826,11 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -13083,13 +11842,6 @@ "source-map": "^0.6.0" } }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "license": "MIT" - }, "node_modules/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -13099,55 +11851,6 @@ "memory-pager": "^1.0.2" } }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -13178,19 +11881,6 @@ "node": ">=8" } }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "license": "MIT", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -13214,71 +11904,6 @@ "node": ">= 0.4" } }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "license": "MIT", - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", - "license": "MIT", - "dependencies": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "license": "MIT", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "node_modules/stream-http/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/stream-splicer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", - "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -13474,12 +12099,12 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -13551,9 +12176,9 @@ "license": "ISC" }, "node_modules/stylelint": { - "version": "16.26.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.26.1.tgz", - "integrity": "sha512-v20V59/crfc8sVTAtge0mdafI3AdnzQ2KsWe6v523L4OA1bJO02S7MO2oyXDCS6iWb9ckIPnqAFVItqSBQr7jw==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.4.0.tgz", + "integrity": "sha512-3kQ2/cHv3Zt8OBg+h2B8XCx9evEABQIrv4hh3uXahGz/ZEHrTR80zxBiK2NfXNaSoyBzxO1pjsz1Vhdzwn5XSw==", "dev": true, "funding": [ { @@ -13568,57 +12193,55 @@ "license": "MIT", "peer": true, "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-syntax-patches-for-csstree": "^1.0.19", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3", - "@csstools/selector-specificity": "^5.0.0", - "@dual-bundle/import-meta-resolve": "^4.2.1", - "balanced-match": "^2.0.0", + "@csstools/css-calc": "^3.1.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-syntax-patches-for-csstree": "^1.0.27", + "@csstools/css-tokenizer": "^4.0.0", + "@csstools/media-query-list-parser": "^5.0.0", + "@csstools/selector-resolve-nested": "^4.0.0", + "@csstools/selector-specificity": "^6.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.3", + "css-functions-list": "^3.3.3", "css-tree": "^3.1.0", "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^11.1.1", + "file-entry-cache": "^11.1.2", "global-modules": "^2.0.0", - "globby": "^11.1.0", + "globby": "^16.1.0", "globjoin": "^0.1.4", - "html-tags": "^3.3.1", + "html-tags": "^5.1.0", "ignore": "^7.0.5", + "import-meta-resolve": "^4.2.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.37.0", - "mathml-tag-names": "^2.1.3", - "meow": "^13.2.0", + "mathml-tag-names": "^4.0.0", + "meow": "^14.0.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.5.6", - "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", - "postcss-selector-parser": "^7.1.0", + "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "supports-hyperlinks": "^3.2.0", + "string-width": "^8.1.1", + "supports-hyperlinks": "^4.4.0", "svg-tags": "^1.0.0", "table": "^6.9.0", - "write-file-atomic": "^5.0.1" + "write-file-atomic": "^7.0.0" }, "bin": { "stylelint": "bin/stylelint.mjs" }, "engines": { - "node": ">=18.12.0" + "node": ">=20.19.0" } }, "node_modules/stylelint-config-recess-order": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-7.6.0.tgz", - "integrity": "sha512-c3LXX4a8UEtrMD/KigK4I7LFexbM2p/eSTqnix5dmmvydEqX3dzrRt981h8giSEhA51vxdCEefQc3umH60i2bA==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-7.6.1.tgz", + "integrity": "sha512-ac0H/Iy2chh1YBADrua87G+nJCmG/SdG7gjnoLvtfpN0D+RuNfuADawfbCKvm0LMp5hvuRFNkJsu6xNoLM5ToA==", "dev": true, "license": "ISC", "peerDependencies": { @@ -13627,9 +12250,9 @@ } }, "node_modules/stylelint-config-recommended": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-17.0.0.tgz", - "integrity": "sha512-WaMSdEiPfZTSFVoYmJbxorJfA610O0tlYuU2aEwY33UQhSPgFbClrVJYWvy3jGJx+XW37O+LyNLiZOEXhKhJmA==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-18.0.0.tgz", + "integrity": "sha512-mxgT2XY6YZ3HWWe3Di8umG6aBmWmHTblTgu/f10rqFXnyWxjKWwNdjSWkgkwCtxIKnqjSJzvFmPT5yabVIRxZg==", "dev": true, "funding": [ { @@ -13643,10 +12266,10 @@ ], "license": "MIT", "engines": { - "node": ">=18.12.0" + "node": ">=20.19.0" }, "peerDependencies": { - "stylelint": "^16.23.0" + "stylelint": "^17.0.0" } }, "node_modules/stylelint-order": { @@ -13667,30 +12290,6 @@ "stylelint": "^16.18.0 || ^17.0.0" } }, - "node_modules/stylelint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint/node_modules/balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true, - "license": "MIT" - }, - "node_modules/stylelint/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, "node_modules/stylelint/node_modules/file-entry-cache": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.2.tgz", @@ -13724,40 +12323,33 @@ } }, "node_modules/stylelint/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", + "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">=8" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stylelint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/stylelint/node_modules/write-file-atomic": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz", + "integrity": "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "ansi-regex": "^5.0.1" + "signal-exit": "^4.0.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==", - "license": "MIT", - "dependencies": { - "minimist": "^1.1.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/superagent": { @@ -13831,22 +12423,48 @@ } }, "node_modules/supports-hyperlinks": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", - "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-4.4.0.tgz", + "integrity": "sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg==", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" + "has-flag": "^5.0.1", + "supports-color": "^10.2.2" }, "engines": { - "node": ">=14.18" + "node": ">=20" }, "funding": { "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", + "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -13888,15 +12506,6 @@ "url": "https://opencollective.com/synckit" } }, - "node_modules/syntax-error": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", - "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", - "license": "MIT", - "dependencies": { - "acorn-node": "^1.2.0" - } - }, "node_modules/table": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", @@ -13915,9 +12524,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -14020,38 +12629,10 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "license": "MIT" - }, - "node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/timers-browserify": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==", - "dependencies": { - "process": "~0.11.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -14068,7 +12649,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -14086,7 +12666,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, "license": "MIT", "peer": true, "engines": { @@ -14097,22 +12676,22 @@ } }, "node_modules/tldts": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.21.tgz", - "integrity": "sha512-Plu6V8fF/XU6d2k8jPtlQf5F4Xx2hAin4r2C2ca7wR8NK5MbRTo9huLUWRe28f3Uk8bYZfg74tit/dSjc18xnw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.24.tgz", + "integrity": "sha512-1r6vQTTt1rUiJkI5vX7KG8PR342Ru/5Oh13kEQP2SMbRSZpOey9SrBe27IDxkoWulx8ShWu4K6C0BkctP8Z1bQ==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.0.21" + "tldts-core": "^7.0.24" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.21.tgz", - "integrity": "sha512-oVOMdHvgjqyzUZH1rOESgJP1uNe2bVrfK0jUHHmiM2rpEiRbf3j4BrsIc6JigJRbHGanQwuZv/R+LTcHsw+bLA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.24.tgz", + "integrity": "sha512-pj7yygNMoMRqG7ML2SDQ0xNIOfN3IBDUcPVM2Sg6hP96oFNN2nqnzHreT3z9xLq85IWJyNTvD38O002DdOrPMw==", "dev": true, "license": "MIT" }, @@ -14123,63 +12702,11 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/to-buffer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", - "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", - "license": "MIT", - "dependencies": { - "isarray": "^2.0.5", - "safe-buffer": "^5.2.1", - "typed-array-buffer": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "license": "MIT", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -14188,69 +12715,6 @@ "node": ">=8.0" } }, - "node_modules/to-regex/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -14260,15 +12724,6 @@ "node": ">=0.6" } }, - "node_modules/touch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", - "license": "ISC", - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, "node_modules/tough-cookie": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", @@ -14321,15 +12776,8 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "license": "MIT" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14384,6 +12832,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -14457,12 +12906,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "license": "MIT" - }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -14478,15 +12921,6 @@ "node": ">=14.17" } }, - "node_modules/umd": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", - "license": "MIT", - "bin": { - "umd": "bin/cli.js" - } - }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -14506,32 +12940,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/undeclared-identifiers": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", - "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", - "license": "Apache-2.0", - "dependencies": { - "acorn-node": "^1.3.0", - "dash-ast": "^1.0.0", - "get-assigned-identifiers": "^1.2.0", - "simple-concat": "^1.0.0", - "xtend": "^4.0.1" - }, - "bin": { - "undeclared-identifiers": "bin.js" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "license": "MIT" - }, "node_modules/undici": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.20.0.tgz", - "integrity": "sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==", + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", + "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", "dev": true, "license": "MIT", "engines": { @@ -14539,10 +12951,10 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "devOptional": true, "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -14585,19 +12997,17 @@ "node": ">=4" } }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "node_modules/unicorn-magic": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", + "dev": true, "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/universalify": { @@ -14653,70 +13063,6 @@ "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "license": "MIT", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "license": "MIT", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "license": "MIT", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "license": "MIT", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", @@ -14757,74 +13103,25 @@ "punycode": "^2.1.0" } }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "license": "MIT" - }, - "node_modules/url": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", - "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", - "license": "MIT", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.12.3" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/url-template": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==", "license": "BSD" }, - "node_modules/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "license": "MIT" - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/utf8-byte-length": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", "license": "(WTFPL OR MIT)" }, - "node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "license": "MIT", - "dependencies": { - "inherits": "2.0.3" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, "license": "MIT" }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "license": "ISC" - }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -14849,58 +13146,110 @@ "node": ">= 0.8" } }, - "node_modules/vitreum": { - "version": "6.0.4", - "resolved": "git+https://git@github.com/calculuschild/vitreum.git#929c351881c4229550374421c7e2890a94f4dca7", - "hasInstallScript": true, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "license": "MIT", + "peer": true, "dependencies": { - "browserify": "^16.5.0", - "fs-extra": "^9.0.1", - "livereload": "^0.9.1", - "nodemon": "^2.0.2", - "source-map-support": "^0.5.16", - "through2": "^3.0.1", - "watchify": "^3.11.1" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, - "peerDependencies": { - "@babel/core": "^7.9.0", - "@babel/preset-react": "^7.9.4", - "less": "^3.11.1", - "react": "^18.3.1", - "react-dom": "^18.3.1" - } - }, - "node_modules/vitreum/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": ">=10" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } } }, - "node_modules/vitreum/node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "license": "MIT" + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", @@ -14925,314 +13274,6 @@ "makeerror": "1.0.12" } }, - "node_modules/watchify": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.11.1.tgz", - "integrity": "sha512-WwnUClyFNRMB2NIiHgJU9RQPQNqVeFk7OmZaWf5dC5EnNa0Mgr7imBydbaJ7tGTuPM2hz1Cb4uiBvK9NVxMfog==", - "license": "MIT", - "dependencies": { - "anymatch": "^2.0.0", - "browserify": "^16.1.0", - "chokidar": "^2.1.1", - "defined": "^1.0.0", - "outpipe": "^1.1.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "bin": { - "watchify": "bin/cmd.js" - } - }, - "node_modules/watchify/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "license": "ISC", - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/watchify/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "license": "MIT", - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "license": "MIT", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "license": "MIT", - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/watchify/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "Upgrade to fsevents v2 to mitigate potential security issues", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/watchify/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "license": "ISC", - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/watchify/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/watchify/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/watchify/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/watchify/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", @@ -15263,9 +13304,9 @@ } }, "node_modules/whatwg-url": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.0.tgz", - "integrity": "sha512-9CcxtEKsf53UFwkSUZjG+9vydAsFO4lFHBpJUtjBcoJOCJpKnSJNwCw813zrYJHpCJ7sgfbtOe0V5Ku7Pa1XMQ==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", "dev": true, "license": "MIT", "dependencies": { @@ -15363,6 +13404,7 @@ "version": "1.1.20", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -15504,27 +13546,6 @@ "integrity": "sha512-LhQ68uUnzHH0bwm/QiGA9JwqgadSDOwqB2AIs/LBsrOY6ScqVXKRN2slTCeKAhstDBJ/Of/Yxcjn0pnQmVlmtg==", "license": "MIT" }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/xml-name-validator": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", @@ -15542,15 +13563,6 @@ "dev": true, "license": "MIT" }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index b12edd6be..7af3f61cb 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,8 @@ "url": "git://github.com/naturalcrit/homebrewery.git" }, "scripts": { - "dev": "node --experimental-require-module scripts/dev.js", - "quick": "node --experimental-require-module scripts/quick.js", - "build": "node --experimental-require-module scripts/buildHomebrew.js && node --experimental-require-module scripts/buildAdmin.js", - "builddev": "node --experimental-require-module scripts/buildHomebrew.js --dev", + "start": "node server.js", + "build": "vite build", "lint": "eslint --fix", "lint:dry": "eslint", "stylelint": "stylelint --fix **/*.{less}", @@ -44,7 +42,6 @@ "phb": "node --experimental-require-module scripts/phb.js", "prod": "set NODE_ENV=production && npm run build", "postinstall": "npm run build", - "start": "node --experimental-require-module server.js", "docker:build": "docker build -t ${DOCKERID}/homebrewery:$npm_package_version .", "docker:publish": "docker login && docker push ${DOCKERID}/homebrewery:$npm_package_version" }, @@ -61,10 +58,11 @@ "server" ], "transformIgnorePatterns": [ - "node_modules/(?!(nanoid|@exodus/bytes|parse5)/)" + "node_modules/(?!(nanoid|@exodus/bytes|parse5|@asamuzakjp|@csstools)/)" ], "transform": { - "^.+\\.js$": "babel-jest" + "^.+\\.[jt]s$": "babel-jest", + "^.+\\.mjs$": "babel-jest" }, "coveragePathIgnorePatterns": [ "build/*" @@ -92,10 +90,11 @@ "@babel/plugin-transform-runtime": "^7.29.0", "@babel/preset-env": "^7.29.0", "@babel/preset-react": "^7.28.5", - "@babel/runtime": "^7.28.4", + "@babel/runtime": "^7.28.6", "@dmsnell/diff-match-patch": "^1.1.0", - "@googleapis/drive": "^19.2.0", + "@googleapis/drive": "^20.1.0", "@sanity/diff-match-patch": "^3.2.0", + "@vitejs/plugin-react": "^5.1.2", "body-parser": "^2.2.0", "classnames": "^2.5.1", "codemirror": "^5.65.6", @@ -104,7 +103,6 @@ "cors": "^2.8.5", "create-react-class": "^15.7.0", "dedent": "^1.7.1", - "expr-eval": "^2.0.2", "express": "^5.1.0", "express-async-handler": "^1.2.0", "express-static-gzip": "3.0.0", @@ -114,7 +112,7 @@ "idb-keyval": "^6.2.2", "js-yaml": "^4.1.1", "jwt-simple": "^0.5.6", - "less": "^3.13.1", + "less": "^4.5.1", "lodash": "^4.17.21", "marked": "15.0.12", "marked-alignment-paragraphs": "^1.0.0", @@ -128,21 +126,19 @@ "marked-variables": "^1.0.5", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^9.1.5", + "mongoose": "^9.2.1", "nanoid": "5.1.6", "nconf": "^0.13.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-frame-component": "^4.1.3", - "react-router": "^7.9.6", - "romans": "^3.1.0", + "node": "^25.7.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-frame-component": "^5.2.7", + "react-router": "^7.13.1", "sanitize-filename": "1.6.3", - "superagent": "^10.2.1", - "vitreum": "git+https://git@github.com/calculuschild/vitreum.git", - "written-number": "^0.11.1" + "superagent": "^10.2.1" }, "devDependencies": { - "@stylistic/stylelint-plugin": "^4.0.0", + "@stylistic/stylelint-plugin": "^5.0.1", "babel-jest": "^30.2.0", "babel-plugin-transform-import-meta": "^2.3.3", "eslint": "^9.39.1", @@ -151,12 +147,13 @@ "globals": "^16.4.0", "jest": "^30.2.0", "jest-expect-message": "^1.1.3", - "jsdom": "^28.0.0", + "jsdom": "^28.1.0", "jsdom-global": "^3.0.2", "postcss-less": "^6.0.0", - "stylelint": "^16.25.0", - "stylelint-config-recess-order": "^7.3.0", - "stylelint-config-recommended": "^17.0.0", - "supertest": "^7.1.4" + "stylelint": "^17.4.0", + "stylelint-config-recess-order": "^7.6.1", + "stylelint-config-recommended": "^18.0.0", + "supertest": "^7.1.4", + "vite": "^7.3.1" } } diff --git a/scripts/buildAdmin.js b/scripts/buildAdmin.js deleted file mode 100644 index 9c77315ef..000000000 --- a/scripts/buildAdmin.js +++ /dev/null @@ -1,32 +0,0 @@ - -import fs from 'fs-extra'; -import Proj from './project.json' with { type: 'json' }; -import vitreum from 'vitreum'; -const { pack } = vitreum; - -import lessTransform from 'vitreum/transforms/less.js'; -import assetTransform from 'vitreum/transforms/asset.js'; - -const isDev = !!process.argv.find((arg)=>arg=='--dev'); - -const transforms = { - '.less' : lessTransform, - '*' : assetTransform('./build') -}; - -const build = async ({ bundle, render, ssr })=>{ - const css = await lessTransform.generate({ paths: './shared' }); - await fs.outputFile('./build/admin/bundle.css', css); - await fs.outputFile('./build/admin/bundle.js', bundle); - await fs.outputFile('./build/admin/ssr.cjs', ssr); -}; - -fs.emptyDirSync('./build/admin'); -pack('./client/admin/admin.jsx', { - paths : ['./shared'], - libs : Proj.libs, - dev : isDev && build, - transforms -}) - .then(build) - .catch(console.error); diff --git a/scripts/buildHomebrew.js b/scripts/buildHomebrew.js deleted file mode 100644 index 4d55a4176..000000000 --- a/scripts/buildHomebrew.js +++ /dev/null @@ -1,169 +0,0 @@ -import fs from 'fs-extra'; -import zlib from 'zlib'; -import Proj from './project.json' with { type: 'json' }; -import vitreum from 'vitreum'; -const { pack, watchFile, livereload } = vitreum; - -import lessTransform from 'vitreum/transforms/less.js'; -import assetTransform from 'vitreum/transforms/asset.js'; -import babel from '@babel/core'; -import babelConfig from '../babel.config.json' with { type : 'json' }; -import less from 'less'; - -const isDev = !!process.argv.find((arg)=>arg === '--dev'); - -const babelify = async (code)=>(await babel.transformAsync(code, babelConfig)).code; - -const transforms = { - '.js' : (code, filename, opts)=>babelify(code), - '.jsx' : (code, filename, opts)=>babelify(code), - '.less' : lessTransform, - '*' : assetTransform('./build') -}; - -const build = async ({ bundle, render, ssr })=>{ - const css = await lessTransform.generate({ paths: './shared' }); - //css = `@layer bundle {\n${css}\n}`; - await fs.outputFile('./build/homebrew/bundle.css', css); - await fs.outputFile('./build/homebrew/bundle.js', bundle); - await fs.outputFile('./build/homebrew/ssr.cjs', ssr); - - await fs.copy('./client/homebrew/favicon.ico', './build/assets/favicon.ico'); - - //compress files in production - if(!isDev){ - await fs.outputFile('./build/homebrew/bundle.css.br', zlib.brotliCompressSync(css)); - await fs.outputFile('./build/homebrew/bundle.js.br', zlib.brotliCompressSync(bundle)); - await fs.outputFile('./build/homebrew/ssr.js.br', zlib.brotliCompressSync(ssr)); - } else { - await fs.remove('./build/homebrew/bundle.css.br'); - await fs.remove('./build/homebrew/bundle.js.br'); - await fs.remove('./build/homebrew/ssr.js.br'); - } -}; - -fs.emptyDirSync('./build'); - - -(async ()=>{ - - //v==----------------------------- COMPILE THEMES --------------------------------==v// - - // Update list of all Theme files - const themes = { Legacy: {}, V3: {} }; - - let themeFiles = fs.readdirSync('./themes/Legacy'); - for (const dir of themeFiles) { - const themeData = JSON.parse(fs.readFileSync(`./themes/Legacy/${dir}/settings.json`).toString()); - themeData.path = dir; - themes.Legacy[dir] = (themeData); - //fs.copy(`./themes/Legacy/${dir}/dropdownTexture.png`, `./build/themes/Legacy/${dir}/dropdownTexture.png`); - const src = `./themes/Legacy/${dir}/style.less`; - ((outputDirectory)=>{ - less.render(fs.readFileSync(src).toString(), { - compress : !isDev - }, function(e, output) { - fs.outputFile(outputDirectory, output.css); - }); - })(`./build/themes/Legacy/${dir}/style.css`); - - } - - themeFiles = fs.readdirSync('./themes/V3'); - for (const dir of themeFiles) { - const themeData = JSON.parse(fs.readFileSync(`./themes/V3/${dir}/settings.json`).toString()); - themeData.path = dir; - themes.V3[dir] = (themeData); - fs.copy(`./themes/V3/${dir}/dropdownTexture.png`, `./build/themes/V3/${dir}/dropdownTexture.png`); - fs.copy(`./themes/V3/${dir}/dropdownPreview.png`, `./build/themes/V3/${dir}/dropdownPreview.png`); - const src = `./themes/V3/${dir}/style.less`; - ((outputDirectory)=>{ - less.render(fs.readFileSync(src).toString(), { - compress : !isDev - }, function(e, output) { - fs.outputFile(outputDirectory, output.css); - }); - })(`./build/themes/V3/${dir}/style.css`); - } - - await fs.outputFile('./themes/themes.json', JSON.stringify(themes, null, 2)); - - // await less.render(lessCode, { - // compress : !dev, - // sourceMap : (dev ? { - // sourceMapFileInline: true, - // outputSourceFiles: true - // } : false), - // }) - - // Move assets - await fs.copy('./themes/fonts', './build/fonts'); - await fs.copy('./themes/assets', './build/assets'); - await fs.copy('./client/icons', './build/icons'); - - //v==---------------------------MOVE CM EDITOR THEMES -----------------------------==v// - - const editorThemesBuildDir = './build/homebrew/cm-themes'; - await fs.copy('./node_modules/codemirror/theme', editorThemesBuildDir); - await fs.copy('./themes/codeMirror/customThemes', editorThemesBuildDir); - const editorThemeFiles = fs.readdirSync(editorThemesBuildDir); - - const editorThemeFile = './themes/codeMirror/editorThemes.json'; - if(fs.existsSync(editorThemeFile)) fs.rmSync(editorThemeFile); - const stream = fs.createWriteStream(editorThemeFile, { flags: 'a' }); - stream.write('[\n"default"'); - - for (const themeFile of editorThemeFiles) { - stream.write(`,\n"${themeFile.slice(0, -4)}"`); - } - stream.write('\n]\n'); - stream.end(); - - - await fs.copy('./themes/codeMirror', './build/homebrew/codeMirror'); - - //v==----------------------------- BUNDLE PACKAGES --------------------------------==v// - - const bundles = await pack('./client/homebrew/homebrew.jsx', { - paths : ['./shared', './'], - libs : Proj.libs, - dev : isDev && build, - transforms - }); - build(bundles); - - // Possible method for generating separate bundles for theme snippets: factor-bundle first sending all common files to bundle.js, then again using default settings, keeping only snippet bundles - // await fs.outputFile('./build/junk.js', ''); - // await fs.outputFile('./build/themes/Legacy/5ePHB/snippets.js', ''); - // - // const files = ['./client/homebrew/homebrew.jsx','./themes/Legacy/5ePHB/snippets.js']; - // - // bundles = await pack(files, { - // dedupe: false, - // plugin : [['factor-bundle', { outputs: [ './build/junk.js','./build/themes/Legacy/5ePHB/snippets.js'], threshold : function(row, groups) { - // console.log(groups); - // if (groups.some(group => /.*homebrew.jsx$/.test(group))) { - // console.log("found homebrewery") - // return true; - // } - // return this._defaultThreshold(row, groups); - // }}]], - // paths : ['./shared','./','./build'], - // libs : Proj.libs, - // dev : isDev && build, - // transforms - // }); - // build(bundles); - // - - //In development, set up LiveReload (refreshes browser), and Nodemon (restarts server) - if(isDev){ - livereload('./build'); // Install the Chrome extension LiveReload to automatically refresh the browser - watchFile('./server.js', { // Restart server when change detected to this file or any nested directory from here - ignore : ['./build', './client', './themes'], // Ignore folders that are not running server code / avoids unneeded restarts - ext : 'js json' // Extensions to watch (only .js/.json by default) - //watch : ['./server', './themes'], // Watch additional folders if needed - }); - } - -})().catch(console.error); \ No newline at end of file diff --git a/scripts/dev.js b/scripts/dev.js deleted file mode 100644 index 45f6c3d99..000000000 --- a/scripts/dev.js +++ /dev/null @@ -1,22 +0,0 @@ -const label = 'dev'; -console.time(label); - -const jsx = require('vitreum/steps/jsx.watch.js'); -const less = require('vitreum/steps/less.watch.js'); -const assets = require('vitreum/steps/assets.watch.js'); -const server = require('vitreum/steps/server.watch.js'); -const livereload = require('vitreum/steps/livereload.js'); - -const Proj = require('./project.json'); - -Promise.resolve() - .then(()=>jsx('homebrew', './client/homebrew/homebrew.jsx', { libs: Proj.libs, shared: ['./shared'] })) - .then((deps)=>less('homebrew', { shared: ['./shared'] }, deps)) - .then(()=>jsx('admin', './client/admin/admin.jsx', { libs: Proj.libs, shared: ['./shared'] })) - .then((deps)=>less('admin', { shared: ['./shared'] }, deps)) - - .then(()=>assets(Proj.assets, ['./shared', './client'])) - .then(()=>livereload()) - .then(()=>server('./server.js', ['server'])) - .then(console.timeEnd.bind(console, label)) - .catch(console.error); \ No newline at end of file diff --git a/scripts/quick.js b/scripts/quick.js deleted file mode 100644 index e763d85f7..000000000 --- a/scripts/quick.js +++ /dev/null @@ -1,17 +0,0 @@ -const label = 'quick'; -console.time(label); - -const jsx = require('vitreum/steps/jsx.js').partial; -const less = require('vitreum/steps/less.js').partial; -const server = require('vitreum/steps/server.watch.js').partial; - -const Proj = require('./project.json'); - -Promise.resolve() - .then(jsx('homebrew', './client/homebrew/homebrew.jsx', Proj.libs, ['./shared'])) - .then(less('homebrew', ['./shared'])) - .then(jsx('admin', './client/admin/admin.jsx', Proj.libs, ['./shared'])) - .then(less('admin', ['./shared'])) - .then(server('./server.js', ['server'])) - .then(console.timeEnd.bind(console, label)) - .catch(console.error); \ No newline at end of file diff --git a/server.js b/server.js index fe5a9a363..db97336e2 100644 --- a/server.js +++ b/server.js @@ -1,12 +1,29 @@ -import DB from './server/db.js'; -import server from './server/app.js'; +import DB from './server/db.js'; +import createApp from './server/app.js'; import config from './server/config.js'; +import { createServer as createViteServer } from 'vite'; -DB.connect(config).then(()=>{ - // Ensure that we have successfully connected to the database - // before launching server - const PORT = process.env.PORT || config.get('web_port') || 8000; - server.listen(PORT, ()=>{ +const isDev = process.env.NODE_ENV === 'local'; + +async function start() { + let vite; + + if(isDev) { + vite = await createViteServer({ + server : { middlewareMode: true }, + appType : 'custom', + }); + } + + await DB.connect(config).catch((err)=>{ + console.error('Database connection failed:', err); + process.exit(1); + }); + + const app = await createApp(vite); + + const PORT = process.env.PORT || config.get('web_port') || 3000; + app.listen(PORT, ()=>{ const reset = '\x1b[0m'; // Reset to default style const bright = '\x1b[1m'; // Bright (bold) style const cyan = '\x1b[36m'; // Cyan color @@ -14,7 +31,10 @@ DB.connect(config).then(()=>{ console.log(`\n\tserver started at: ${new Date().toLocaleString()}`); console.log(`\tserver on port: ${PORT}`); - console.log(`\t${bright + cyan}Open in browser: ${reset}${underline + bright + cyan}http://localhost:${PORT}${reset}\n\n`); - + console.log( + `\t${bright + cyan}Open in browser: ${reset}${underline + bright + cyan}http://localhost:${PORT}${reset}\n\n`, + ); }); -}); +} + +start(); diff --git a/server/admin.api.js b/server/admin.api.js index a3d7622f1..f55eefdf2 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -4,64 +4,69 @@ import { model as NotificationModel } from './notifications.model.js'; import express from 'express'; import Moment from 'moment'; import zlib from 'zlib'; -import templateFn from '../client/template.js'; +import config from './config.js'; +import path from 'path'; +import fs from 'fs-extra'; + +const nodeEnv = config.get('node_env'); +const isProd = nodeEnv === 'production'; import HomebrewAPI from './homebrew.api.js'; import asyncHandler from 'express-async-handler'; import { splitTextStyleAndMetadata } from '../shared/helpers.js'; -const router = express.Router(); - - process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3'; -const mw = { - adminOnly : (req, res, next)=>{ - if(!req.get('authorization')){ - return res +export default function createAdminApi(vite) { + const router = express.Router(); + + const mw = { + adminOnly : (req, res, next)=>{ + if(!req.get('authorization')){ + return res .set('WWW-Authenticate', 'Basic realm="Authorization Required"') .status(401) .send('Authorization Required'); - } - const [username, password] = Buffer.from(req.get('authorization').split(' ').pop(), 'base64') + } + const [username, password] = Buffer.from(req.get('authorization').split(' ').pop(), 'base64') .toString('ascii') .split(':'); - if(process.env.ADMIN_USER === username && process.env.ADMIN_PASS === password){ - return next(); + if(process.env.ADMIN_USER === username && process.env.ADMIN_PASS === password){ + return next(); + } + throw { HBErrorCode: '52', code: 401, message: 'Access denied' }; } - throw { HBErrorCode: '52', code: 401, message: 'Access denied' }; - } -}; + }; -const junkBrewPipeline = [ - { $match : { - updatedAt : { $lt: Moment().subtract(30, 'days').toDate() }, - lastViewed : { $lt: Moment().subtract(30, 'days').toDate() } - } }, - { $project: { textBinSize: { $binarySize: '$textBin' } } }, - { $match: { textBinSize: { $lt: 140 } } }, - { $limit: 100 } -]; + const junkBrewPipeline = [ + { $match : { + updatedAt : { $lt: Moment().subtract(30, 'days').toDate() }, + lastViewed : { $lt: Moment().subtract(30, 'days').toDate() } + } }, + { $project: { textBinSize: { $binarySize: '$textBin' } } }, + { $match: { textBinSize: { $lt: 140 } } }, + { $limit: 100 } + ]; -/* Search for brews that aren't compressed (missing the compressed text field) */ -const uncompressedBrewQuery = HomebrewModel.find({ - 'text' : { '$exists': true } -}).lean().limit(10000).select('_id'); + /* Search for brews that aren't compressed (missing the compressed text field) */ + const uncompressedBrewQuery = HomebrewModel.find({ + 'text' : { '$exists': true } + }).lean().limit(10000).select('_id'); -// Search for up to 100 brews that have not been viewed or updated in 30 days and are shorter than 140 bytes -router.get('/admin/cleanup', mw.adminOnly, (req, res)=>{ - HomebrewModel.aggregate(junkBrewPipeline).option({ maxTimeMS: 60000 }) + // Search for up to 100 brews that have not been viewed or updated in 30 days and are shorter than 140 bytes + router.get('/admin/cleanup', mw.adminOnly, (req, res)=>{ + HomebrewModel.aggregate(junkBrewPipeline).option({ maxTimeMS: 60000 }) .then((objs)=>res.json({ count: objs.length })) .catch((error)=>{ console.error(error); res.status(500).json({ error: 'Internal Server Error' }); }); -}); + }); -// Delete up to 100 brews that have not been viewed or updated in 30 days and are shorter than 140 bytes -router.post('/admin/cleanup', mw.adminOnly, (req, res)=>{ - HomebrewModel.aggregate(junkBrewPipeline).option({ maxTimeMS: 60000 }) + // Delete up to 100 brews that have not been viewed or updated in 30 days and are shorter than 140 bytes + router.post('/admin/cleanup', mw.adminOnly, (req, res)=>{ + HomebrewModel.aggregate(junkBrewPipeline).option({ maxTimeMS: 60000 }) .then((docs)=>{ const ids = docs.map((doc)=>doc._id); return HomebrewModel.deleteMany({ _id: { $in: ids } }); @@ -71,18 +76,18 @@ router.post('/admin/cleanup', mw.adminOnly, (req, res)=>{ console.error(error); res.status(500).json({ error: 'Internal Server Error' }); }); -}); + }); -/* Searches for matching edit or share id, also attempts to partial match */ -router.get('/admin/lookup/:id', mw.adminOnly, asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res, next)=>{ - return res.json(req.brew); -}); + /* Searches for matching edit or share id, also attempts to partial match */ + router.get('/admin/lookup/:id', mw.adminOnly, asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res, next)=>{ + return res.json(req.brew); + }); -/* Find 50 brews that aren't compressed yet */ -router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{ - const query = uncompressedBrewQuery.clone(); + /* Find 50 brews that aren't compressed yet */ + router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{ + const query = uncompressedBrewQuery.clone(); - query.exec() + query.exec() .then((objs)=>{ const ids = objs.map((obj)=>obj._id); res.json({ count: ids.length, ids }); @@ -91,46 +96,46 @@ router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{ console.error(err); res.status(500).send(err.message || 'Internal Server Error'); }); -}); - -/* Cleans `` from the "text" field of a brew */ -router.put('/admin/clean/script/:id', asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res)=>{ - console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Cleaning script tags from ShareID ${req.params.id}`); - - function cleanText(text){return text.replaceAll(/(<\/?s)cript/gi, '');}; - - const brew = req.brew; - - const properties = ['text', 'description', 'title']; - properties.forEach((property)=>{ - brew[property] = cleanText(brew[property]); }); - splitTextStyleAndMetadata(brew); + /* Cleans `` from the "text" field of a brew */ + router.put('/admin/clean/script/:id', asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res)=>{ + console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Cleaning script tags from ShareID ${req.params.id}`); - req.body = brew; + function cleanText(text){return text.replaceAll(/(<\/?s)cript/gi, '');}; - // Remove Account from request to prevent Admin user from being added to brew as an Author - req.account = undefined; + const brew = req.brew; - return await HomebrewAPI.updateBrew(req, res); -}); + const properties = ['text', 'description', 'title']; + properties.forEach((property)=>{ + brew[property] = cleanText(brew[property]); + }); -/* Get list of a user's documents */ -router.get('/admin/user/list/:user', mw.adminOnly, async (req, res)=>{ - const username = req.params.user; - const fields = { _id: 0, text: 0, textBin: 0 }; // Remove unnecessary fields from document lists + splitTextStyleAndMetadata(brew); - console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Get brew list for ${username}`); + req.body = brew; - const brews = await HomebrewModel.getByUser(username, true, fields); + // Remove Account from request to prevent Admin user from being added to brew as an Author + req.account = undefined; - return res.json(brews); -}); + return await HomebrewAPI.updateBrew(req, res); + }); -/* Compresses the "text" field of a brew to binary */ -router.put('/admin/compress/:id', (req, res)=>{ - HomebrewModel.findOne({ _id: req.params.id }) + /* Get list of a user's documents */ + router.get('/admin/user/list/:user', mw.adminOnly, async (req, res)=>{ + const username = req.params.user; + const fields = { _id: 0, text: 0, textBin: 0 }; // Remove unnecessary fields from document lists + + console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Get brew list for ${username}`); + + const brews = await HomebrewModel.getByUser(username, true, fields); + + return res.json(brews); + }); + + /* Compresses the "text" field of a brew to binary */ + router.put('/admin/compress/:id', (req, res)=>{ + HomebrewModel.findOne({ _id: req.params.id }) .then((brew)=>{ if(!brew) return res.status(404).send('Brew not found'); @@ -147,239 +152,252 @@ router.put('/admin/compress/:id', (req, res)=>{ console.error(err); res.status(500).send('Error while saving'); }); -}); + }); -router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ - try { - const totalBrewsCount = await HomebrewModel.countDocuments({}); - const publishedBrewsCount = await HomebrewModel.countDocuments({ published: true }); + router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ + try { + const totalBrewsCount = await HomebrewModel.countDocuments({}); + const publishedBrewsCount = await HomebrewModel.countDocuments({ published: true }); - return res.json({ - totalBrews : totalBrewsCount, - totalPublishedBrews : publishedBrewsCount - }); - } catch (error) { - console.error(error); - return res.status(500).json({ error: 'Internal Server Error' }); - } -}); + return res.json({ + totalBrews : totalBrewsCount, + totalPublishedBrews : publishedBrewsCount + }); + } catch (error) { + console.error(error); + return res.status(500).json({ error: 'Internal Server Error' }); + } + }); -// ####################### LOCKS + // ####################### LOCKS -router.get('/api/lock/count', mw.adminOnly, asyncHandler(async (req, res)=>{ + router.get('/api/lock/count', mw.adminOnly, asyncHandler(async (req, res)=>{ - const countLocksQuery = { - lock : { $exists: true } - }; - const count = await HomebrewModel.countDocuments(countLocksQuery) + const countLocksQuery = { + lock : { $exists: true } + }; + const count = await HomebrewModel.countDocuments(countLocksQuery) .catch((error)=>{ throw { name: 'Lock Count Error', message: 'Unable to get lock count', status: 500, HBErrorCode: '61', error }; }); - return res.json({ count }); + return res.json({ count }); -})); + })); -router.get('/api/locks', mw.adminOnly, asyncHandler(async (req, res)=>{ - const countLocksPipeline = [ - { + router.get('/api/locks', mw.adminOnly, asyncHandler(async (req, res)=>{ + const countLocksPipeline = [ + { $match : { 'lock' : { '$exists': 1 } }, - }, - { - $project : { - shareId : 1, - editId : 1, - title : 1, - lock : 1 + }, + { + $project : { + shareId : 1, + editId : 1, + title : 1, + lock : 1 + } } - } - ]; - const lockedDocuments = await HomebrewModel.aggregate(countLocksPipeline) + ]; + const lockedDocuments = await HomebrewModel.aggregate(countLocksPipeline) .catch((error)=>{ throw { name: 'Can Not Get Locked Brews', message: 'Unable to get locked brew collection', status: 500, HBErrorCode: '68', error }; }); - return res.json({ - lockedDocuments - }); + return res.json({ + lockedDocuments + }); -})); + })); -router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ + router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ - const lock = req.body; + const lock = req.body; - lock.applied = new Date; + lock.applied = new Date; - const filter = { - shareId : req.params.id - }; + const filter = { + shareId : req.params.id + }; - const brew = await HomebrewModel.findOne(filter); + const brew = await HomebrewModel.findOne(filter); - if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to lock', shareId: req.params.id, status: 500, HBErrorCode: '63' }; + if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to lock', shareId: req.params.id, status: 500, HBErrorCode: '63' }; - if(brew.lock && !lock.overwrite) { - throw { name: 'Already Locked', message: 'Lock already exists on brew', shareId: req.params.id, title: brew.title, status: 500, HBErrorCode: '64' }; - } + if(brew.lock && !lock.overwrite) { + throw { name: 'Already Locked', message: 'Lock already exists on brew', shareId: req.params.id, title: brew.title, status: 500, HBErrorCode: '64' }; + } - lock.overwrite = undefined; + lock.overwrite = undefined; - brew.lock = lock; - brew.markModified('lock'); + brew.lock = lock; + brew.markModified('lock'); - await brew.save() + await brew.save() .catch((error)=>{ throw { name: 'Lock Error', message: 'Unable to set lock', shareId: req.params.id, status: 500, HBErrorCode: '62', error }; }); - return res.json({ name: 'LOCKED', message: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); + return res.json({ name: 'LOCKED', message: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); -})); + })); -router.put('/api/unlock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ + router.put('/api/unlock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ - const filter = { - shareId : req.params.id - }; + const filter = { + shareId : req.params.id + }; - const brew = await HomebrewModel.findOne(filter); + const brew = await HomebrewModel.findOne(filter); - if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to unlock', shareId: req.params.id, status: 500, HBErrorCode: '66' }; + if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to unlock', shareId: req.params.id, status: 500, HBErrorCode: '66' }; - if(!brew.lock) throw { name: 'Not Locked', message: 'Cannot unlock as brew is not locked', shareId: req.params.id, status: 500, HBErrorCode: '67' }; + if(!brew.lock) throw { name: 'Not Locked', message: 'Cannot unlock as brew is not locked', shareId: req.params.id, status: 500, HBErrorCode: '67' }; - brew.lock = undefined; - brew.markModified('lock'); + brew.lock = undefined; + brew.markModified('lock'); - await brew.save() + await brew.save() .catch((error)=>{ throw { name: 'Cannot Unlock', message: 'Unable to clear lock', shareId: req.params.id, status: 500, HBErrorCode: '65', error }; }); - return res.json({ name: 'Unlocked', message: `Lock removed from brew ID ${req.params.id}` }); -})); + return res.json({ name: 'Unlocked', message: `Lock removed from brew ID ${req.params.id}` }); + })); -router.get('/api/lock/reviews', mw.adminOnly, asyncHandler(async (req, res)=>{ - const countReviewsPipeline = [ - { + router.get('/api/lock/reviews', mw.adminOnly, asyncHandler(async (req, res)=>{ + const countReviewsPipeline = [ + { $match : { 'lock.reviewRequested' : { '$exists': 1 } }, - }, - { - $project : { - shareId : 1, - editId : 1, - title : 1, - lock : 1 + }, + { + $project : { + shareId : 1, + editId : 1, + title : 1, + lock : 1 + } } - } - ]; - const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline) + ]; + const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline) .catch((error)=>{ throw { name: 'Can Not Get Reviews', message: 'Unable to get review collection', status: 500, HBErrorCode: '68', error }; }); - return res.json({ - reviewDocuments - }); + return res.json({ + reviewDocuments + }); -})); + })); -router.put('/api/lock/review/request/:id', asyncHandler(async (req, res)=>{ + router.put('/api/lock/review/request/:id', asyncHandler(async (req, res)=>{ // === This route is NOT Admin only === // Any user can request a review of their document - const filter = { - shareId : req.params.id, - lock : { $exists: 1 } - }; + const filter = { + shareId : req.params.id, + lock : { $exists: 1 } + }; - const brew = await HomebrewModel.findOne(filter); - if(!brew) { throw { name: 'Brew Not Found', message: `Cannot find a locked brew with ID ${req.params.id}`, code: 500, HBErrorCode: '70' }; }; + const brew = await HomebrewModel.findOne(filter); + if(!brew) { throw { name: 'Brew Not Found', message: `Cannot find a locked brew with ID ${req.params.id}`, code: 500, HBErrorCode: '70' }; }; - if(brew.lock.reviewRequested){ - throw { name: 'Review Already Requested', message: `Review already requested for brew ${brew.shareId} - ${brew.title}`, code: 500, HBErrorCode: '71' }; - }; + if(brew.lock.reviewRequested){ + throw { name: 'Review Already Requested', message: `Review already requested for brew ${brew.shareId} - ${brew.title}`, code: 500, HBErrorCode: '71' }; + }; - brew.lock.reviewRequested = new Date(); - brew.markModified('lock'); + brew.lock.reviewRequested = new Date(); + brew.markModified('lock'); - await brew.save() + await brew.save() .catch((error)=>{ throw { name: 'Can Not Set Review Request', message: `Unable to set request for review on brew ID ${req.params.id}`, code: 500, HBErrorCode: '69', error }; }); - return res.json({ name: 'Review Requested', message: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); + return res.json({ name: 'Review Requested', message: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); -})); + })); -router.put('/api/lock/review/remove/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ + router.put('/api/lock/review/remove/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ - const filter = { - shareId : req.params.id, - 'lock.reviewRequested' : { $exists: 1 } - }; + const filter = { + shareId : req.params.id, + 'lock.reviewRequested' : { $exists: 1 } + }; - const brew = await HomebrewModel.findOne(filter); - if(!brew) { throw { name: 'Can Not Clear Review Request', message: `Brew ID ${req.params.id} does not have a review pending!`, HBErrorCode: '73' }; }; + const brew = await HomebrewModel.findOne(filter); + if(!brew) { throw { name: 'Can Not Clear Review Request', message: `Brew ID ${req.params.id} does not have a review pending!`, HBErrorCode: '73' }; }; - brew.lock.reviewRequested = undefined; - brew.markModified('lock'); + brew.lock.reviewRequested = undefined; + brew.markModified('lock'); - await brew.save() + await brew.save() .catch((error)=>{ throw { name: 'Can Not Clear Review Request', message: `Unable to remove request for review on brew ID ${req.params.id}`, HBErrorCode: '72', error }; }); - return res.json({ name: 'Review Request Cleared', message: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); + return res.json({ name: 'Review Request Cleared', message: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); -})); + })); -// ####################### NOTIFICATIONS + // ####################### NOTIFICATIONS -router.get('/admin/notification/all', async (req, res, next)=>{ - try { - const notifications = await NotificationModel.getAll(); - return res.json(notifications); + router.get('/admin/notification/all', async (req, res, next)=>{ + try { + const notifications = await NotificationModel.getAll(); + return res.json(notifications); - } catch (error) { - console.log('Error getting all notifications: ', error.message); - return res.status(500).json({ message: error.message }); - } -}); - -router.post('/admin/notification/add', mw.adminOnly, async (req, res, next)=>{ - try { - const notification = await NotificationModel.addNotification(req.body); - return res.status(201).json(notification); - } catch (error) { - console.log('Error adding notification: ', error.message); - return res.status(500).json({ message: error.message }); - } -}); - -router.delete('/admin/notification/delete/:id', mw.adminOnly, async (req, res, next)=>{ - try { - const notification = await NotificationModel.deleteNotification(req.params.id); - return res.json(notification); - } catch (error) { - console.error('Error deleting notification: { key: ', req.params.id, ' error: ', error.message, ' }'); - return res.status(500).json({ message: error.message }); - } -}); - -router.get('/admin', mw.adminOnly, (req, res)=>{ - templateFn('admin', { - url : req.originalUrl - }) - .then((page)=>res.send(page)) - .catch((err)=>{ - console.log(err); - res.sendStatus(500); + } catch (error) { + console.log('Error getting all notifications: ', error.message); + return res.status(500).json({ message: error.message }); + } }); -}); -export default router; + router.post('/admin/notification/add', mw.adminOnly, async (req, res, next)=>{ + try { + const notification = await NotificationModel.addNotification(req.body); + return res.status(201).json(notification); + } catch (error) { + console.log('Error adding notification: ', error.message); + return res.status(500).json({ message: error.message }); + } + }); + + router.delete('/admin/notification/delete/:id', mw.adminOnly, async (req, res, next)=>{ + try { + const notification = await NotificationModel.deleteNotification(req.params.id); + return res.json(notification); + } catch (error) { + console.error('Error deleting notification: { key: ', req.params.id, ' error: ', error.message, ' }'); + return res.status(500).json({ message: error.message }); + } + }); + + router.get('/admin', mw.adminOnly, asyncHandler(async (req, res)=>{ + const props = { + url : req.originalUrl + }; + + const htmlPath = isProd + ? path.resolve('build', 'index.html') + : path.resolve('index.html'); + + let html = fs.readFileSync(htmlPath, 'utf-8'); + + if(!isProd && vite?.transformIndexHtml) { + html = await vite.transformIndexHtml(req.originalUrl, html); + } + + res.send(html.replace( + '', + `\n` + )); + })); + + + return router; +} + diff --git a/server/admin.api.spec.js b/server/admin.api.spec.js index e156c6c8f..ce2a06d0d 100644 --- a/server/admin.api.spec.js +++ b/server/admin.api.spec.js @@ -1,30 +1,45 @@ /*eslint max-lines: ["warn", {"max": 1000, "skipBlankLines": true, "skipComments": true}]*/ +import mongoose from 'mongoose'; import supertest from 'supertest'; -import HBApp from './app.js'; +import createApp from './app.js'; import { model as NotificationModel } from './notifications.model.js'; import { model as HomebrewModel } from './homebrew.model.js'; +let app; +let request; +let dbState; -// Mimic https responses to avoid being redirected all the time -const app = supertest.agent(HBApp).set('X-Forwarded-Proto', 'https'); +beforeAll(async ()=>{ + app = await createApp(); + request = supertest.agent(app).set('X-Forwarded-Proto', 'https'); +}); describe('Tests for admin api', ()=>{ + beforeEach(()=>{ + dbState = mongoose.connection.readyState; + mongoose.connection.readyState = 1; + }); + afterEach(()=>{ + mongoose.connection.readyState = dbState; jest.resetAllMocks(); }); + afterAll(async ()=>{ + await mongoose.connection.close(); + }); + describe('Notifications', ()=>{ it('should return list of all notifications', async ()=>{ const testNotifications = ['a', 'b']; - jest.spyOn(NotificationModel, 'find') - .mockImplementationOnce(()=>{ + jest.spyOn(NotificationModel, 'find').mockImplementationOnce(()=>{ return { exec: jest.fn().mockResolvedValue(testNotifications) }; }); - const response = await app - .get('/admin/notification/all') - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + const response = await request + .get('/admin/notification/all') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual(testNotifications); @@ -44,18 +59,17 @@ describe('Tests for admin api', ()=>{ _id : expect.any(String), createdAt : expect.any(String), startAt : inputNotification.startAt, - stopAt : inputNotification.stopAt, + stopAt : inputNotification.stopAt }; - jest.spyOn(NotificationModel.prototype, 'save') - .mockImplementationOnce(function() { - return Promise.resolve(this); - }); + jest.spyOn(NotificationModel.prototype, 'save').mockImplementationOnce(function () { + return Promise.resolve(this); + }); - const response = await app - .post('/admin/notification/add') - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .send(inputNotification); + const response = await request + .post('/admin/notification/add') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(inputNotification); expect(response.status).toBe(201); expect(response.body).toEqual(savedNotification); @@ -69,16 +83,14 @@ describe('Tests for admin api', ()=>{ stopAt : new Date().toISOString() }; - //Change 'save' function to just return itself instead of actually interacting with the database - jest.spyOn(NotificationModel.prototype, 'save') - .mockImplementationOnce(function() { - return Promise.resolve(this); - }); + jest.spyOn(NotificationModel.prototype, 'save').mockImplementationOnce(function () { + return Promise.resolve(this); + }); - const response = await app - .post('/admin/notification/add') - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .send(inputNotification); + const response = await request + .post('/admin/notification/add') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(inputNotification); expect(response.status).toBe(500); expect(response.body).toEqual({ message: 'Dismiss key is required!' }); @@ -87,15 +99,15 @@ describe('Tests for admin api', ()=>{ it('should delete a notification based on its dismiss key', async ()=>{ const dismissKey = 'testKey'; - jest.spyOn(NotificationModel, 'findOneAndDelete') - .mockImplementationOnce((key)=>{ - return { exec: jest.fn().mockResolvedValue(key) }; - }); - const response = await app - .delete(`/admin/notification/delete/${dismissKey}`) - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + jest.spyOn(NotificationModel, 'findOneAndDelete').mockImplementationOnce((key)=>{ + return { exec: jest.fn().mockResolvedValue(key) }; + }); - expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ 'dismissKey': 'testKey' }); + const response = await request + .delete(`/admin/notification/delete/${dismissKey}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + + expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ dismissKey: 'testKey' }); expect(response.status).toBe(200); expect(response.body).toEqual({ dismissKey: 'testKey' }); }); @@ -103,15 +115,15 @@ describe('Tests for admin api', ()=>{ it('should handle error deleting a notification that doesnt exist', async ()=>{ const dismissKey = 'testKey'; - jest.spyOn(NotificationModel, 'findOneAndDelete') - .mockImplementationOnce(()=>{ - return { exec: jest.fn().mockResolvedValue() }; - }); - const response = await app - .delete(`/admin/notification/delete/${dismissKey}`) - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + jest.spyOn(NotificationModel, 'findOneAndDelete').mockImplementationOnce(()=>{ + return { exec: jest.fn().mockResolvedValue() }; + }); - expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ 'dismissKey': 'testKey' }); + const response = await request + .delete(`/admin/notification/delete/${dismissKey}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + + expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ dismissKey: 'testKey' }); expect(response.status).toBe(500); expect(response.body).toEqual({ message: 'Notification not found' }); }); @@ -120,30 +132,24 @@ describe('Tests for admin api', ()=>{ describe('Locks', ()=>{ describe('Count', ()=>{ it('Count of all locked documents', async ()=>{ - const testNumber = 16777216; // 8^8, because why not + const testNumber = 16777216; - jest.spyOn(HomebrewModel, 'countDocuments') - .mockImplementationOnce(()=>{ - return Promise.resolve(testNumber); - }); + jest.spyOn(HomebrewModel, 'countDocuments').mockImplementationOnce(()=>Promise.resolve(testNumber)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/lock/count'); + const response = await request + .get('/api/lock/count') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual({ count: testNumber }); }); it('Handle error while fetching count of locked documents', async ()=>{ - jest.spyOn(HomebrewModel, 'countDocuments') - .mockImplementationOnce(()=>{ - return Promise.reject(); - }); + jest.spyOn(HomebrewModel, 'countDocuments').mockImplementationOnce(()=>Promise.reject()); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/lock/count'); + const response = await request + .get('/api/lock/count') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -151,7 +157,7 @@ describe('Tests for admin api', ()=>{ message : 'Unable to get lock count', name : 'Lock Count Error', originalUrl : '/api/lock/count', - status : 500, + status : 500 }); }); }); @@ -160,28 +166,22 @@ describe('Tests for admin api', ()=>{ it('Get list of all locked documents', async ()=>{ const testLocks = ['a', 'b']; - jest.spyOn(HomebrewModel, 'aggregate') - .mockImplementationOnce(()=>{ - return Promise.resolve(testLocks); - }); + jest.spyOn(HomebrewModel, 'aggregate').mockImplementationOnce(()=>Promise.resolve(testLocks)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/locks'); + const response = await request + .get('/api/locks') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual({ lockedDocuments: testLocks }); }); it('Handle error while fetching list of all locked documents', async ()=>{ - jest.spyOn(HomebrewModel, 'aggregate') - .mockImplementationOnce(()=>{ - return Promise.reject(); - }); + jest.spyOn(HomebrewModel, 'aggregate').mockImplementationOnce(()=>Promise.reject()); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/locks'); + const response = await request + .get('/api/locks') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -196,28 +196,22 @@ describe('Tests for admin api', ()=>{ it('Get list of all locked documents with pending review requests', async ()=>{ const testLocks = ['a', 'b']; - jest.spyOn(HomebrewModel, 'aggregate') - .mockImplementationOnce(()=>{ - return Promise.resolve(testLocks); - }); + jest.spyOn(HomebrewModel, 'aggregate').mockImplementationOnce(()=>Promise.resolve(testLocks)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/lock/reviews'); + const response = await request + .get('/api/lock/reviews') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual({ reviewDocuments: testLocks }); }); it('Handle error while fetching list of all locked documents with pending review requests', async ()=>{ - jest.spyOn(HomebrewModel, 'aggregate') - .mockImplementationOnce(()=>{ - return Promise.reject(); - }); + jest.spyOn(HomebrewModel, 'aggregate').mockImplementationOnce(()=>Promise.reject()); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/lock/reviews'); + const response = await request + .get('/api/lock/reviews') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -235,8 +229,8 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); } + markModified : ()=>true, + save : ()=>Promise.resolve() }; const testLock = { @@ -245,15 +239,12 @@ describe('Tests for admin api', ()=>{ shareMessage : 'share' }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .post(`/api/lock/${testBrew.shareId}`) - .send(testLock); + const response = await request + .post(`/api/lock/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(testLock); expect(response.status).toBe(200); expect(response.body).toMatchObject({ @@ -277,24 +268,21 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : { code : 1, editMessage : 'oldEdit', - shareMessage : 'oldShare', + shareMessage : 'oldShare' } }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .post(`/api/lock/${testBrew.shareId}`) - .send(testLock); + const response = await request + .post(`/api/lock/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(testLock); expect(response.status).toBe(200); expect(response.body).toMatchObject({ @@ -317,24 +305,21 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : { code : 1, editMessage : 'oldEdit', - shareMessage : 'oldShare', + shareMessage : 'oldShare' } }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .post(`/api/lock/${testBrew.shareId}`) - .send(testLock); + const response = await request + .post(`/api/lock/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(testLock); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -352,8 +337,8 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.reject(); } + markModified : ()=>true, + save : ()=>Promise.reject() }; const testLock = { @@ -362,15 +347,12 @@ describe('Tests for admin api', ()=>{ shareMessage : 'share' }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .post(`/api/lock/${testBrew.shareId}`) - .send(testLock); + const response = await request + .post(`/api/lock/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(testLock); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -396,19 +378,17 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/unlock/${testBrew.shareId}`); + const response = await request.put(`/api/unlock/${testBrew.shareId}`).set( + 'Authorization', + `Basic ${Buffer.from('admin:password3').toString('base64')}` + ); expect(response.status).toBe(200); expect(response.body).toEqual({ @@ -421,18 +401,16 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve() }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/unlock/${testBrew.shareId}`); + const response = await request.put(`/api/unlock/${testBrew.shareId}`).set( + 'Authorization', + `Basic ${Buffer.from('admin:password3').toString('base64')}` + ); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -441,7 +419,7 @@ describe('Tests for admin api', ()=>{ name : 'Not Locked', originalUrl : `/api/unlock/${testBrew.shareId}`, shareId : testBrew.shareId, - status : 500, + status : 500 }); }); @@ -456,19 +434,17 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.reject(); }, + markModified : ()=>true, + save : ()=>Promise.reject(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/unlock/${testBrew.shareId}`); + const response = await request.put(`/api/unlock/${testBrew.shareId}`).set( + 'Authorization', + `Basic ${Buffer.from('admin:password3').toString('base64')}` + ); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -494,40 +470,28 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .put(`/api/lock/review/request/${testBrew.shareId}`); + const response = await request.put(`/api/lock/review/request/${testBrew.shareId}`); expect(response.status).toBe(200); expect(response.body).toEqual({ message : `Review requested on brew ID ${testBrew.shareId} - ${testBrew.title}`, - name : 'Review Requested', + name : 'Review Requested' }); }); it('Error when cannot find a locked brew', async ()=>{ - const testBrew = { - shareId : 'shareId' - }; + const testBrew = { shareId: 'shareId' }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(false); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(false)); - - const response = await app - .put(`/api/lock/review/request/${testBrew.shareId}`) - .catch((err)=>{return err;}); + const response = await request.put(`/api/lock/review/request/${testBrew.shareId}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -557,25 +521,20 @@ describe('Tests for admin api', ()=>{ }; jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(false); - }); + .mockImplementationOnce(()=>Promise.resolve(testBrew)); - - const response = await app - .put(`/api/lock/review/request/${testBrew.shareId}`) - .catch((err)=>{return err;}); + const response = await request + .put(`/api/lock/review/request/${testBrew.shareId}`); expect(response.status).toBe(500); expect(response.body).toEqual({ - HBErrorCode : '70', + HBErrorCode : '71', code : 500, - message : `Cannot find a locked brew with ID ${testBrew.shareId}`, - name : 'Brew Not Found', + message : `Review already requested for brew ${testBrew.shareId} - ${testBrew.title}`, + name : 'Review Already Requested', originalUrl : `/api/lock/review/request/${testBrew.shareId}` }); }); - it('Handle error while adding review request to a locked brew', async ()=>{ const testLock = { applied : 'YES', @@ -587,18 +546,14 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.reject(); }, + markModified : ()=>true, + save : ()=>Promise.reject(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .put(`/api/lock/review/request/${testBrew.shareId}`); + const response = await request.put(`/api/lock/review/request/${testBrew.shareId}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -622,19 +577,16 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/lock/review/remove/${testBrew.shareId}`); + const response = await request + .put(`/api/lock/review/remove/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual({ @@ -644,18 +596,13 @@ describe('Tests for admin api', ()=>{ }); it('Error when clearing review request from a brew with no review request', async ()=>{ - const testBrew = { - shareId : 'shareId', - }; + const testBrew = { shareId: 'shareId' }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(false); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(false)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/lock/review/remove/${testBrew.shareId}`); + const response = await request + .put(`/api/lock/review/remove/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -678,19 +625,16 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.reject(); }, + markModified : ()=>true, + save : ()=>Promise.reject(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/lock/review/remove/${testBrew.shareId}`); + const response = await request + .put(`/api/lock/review/remove/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ diff --git a/server/app.js b/server/app.js index 1bdb5aac3..18b1d68bc 100644 --- a/server/app.js +++ b/server/app.js @@ -12,10 +12,9 @@ import _ from 'lodash'; import jwt from 'jwt-simple'; import express from 'express'; import config from './config.js'; +import path from 'path'; import fs from 'fs-extra'; -const app = express(); - import api from './homebrew.api.js'; const { homebrewApi, getBrew, getUsersBrewThemes, getCSS } = api; import adminApi from './admin.api.js'; @@ -24,7 +23,6 @@ import GoogleActions from './googleActions.js'; import serveCompressedStaticAssets from './static-assets.mv.js'; import sanitizeFilename from 'sanitize-filename'; import asyncHandler from 'express-async-handler'; -import templateFn from '../client/template.js'; import { model as HomebrewModel } from './homebrew.model.js'; import { DEFAULT_BREW } from './brewDefaults.js'; @@ -37,599 +35,626 @@ import cookieParser from 'cookie-parser'; import forceSSL from './forcessl.mw.js'; import dbCheck from './middleware/dbCheck.js'; - -const sanitizeBrew = (brew, accessType)=>{ - brew._id = undefined; - brew.__v = undefined; - if(accessType !== 'edit' && accessType !== 'shareAuthor') { - brew.editId = undefined; - } - return brew; -}; - -app.set('trust proxy', 1 /* number of proxies between user and server */); - -app.use('/', serveCompressedStaticAssets(`build`)); -app.use(contentNegotiation); -app.use(bodyParser.json({ limit: '25mb' })); -app.use(cookieParser()); -app.use(forceSSL); - import cors from 'cors'; -const nodeEnv = config.get('node_env'); -const isLocalEnvironment = config.get('local_environments').includes(nodeEnv); +export default async function createApp(vite) { + const app = express(); -const corsOptions = { - origin : (origin, callback)=>{ + const nodeEnv = config.get('node_env'); + const isProd = nodeEnv === 'production'; + const isLocalEnvironment = config.get('local_environments').includes(nodeEnv); - const allowedOrigins = [ - 'https://homebrewery.naturalcrit.com', - 'https://www.naturalcrit.com', - 'https://naturalcrit-stage.herokuapp.com', - 'https://homebrewery-stage.herokuapp.com', - ]; - - const localNetworkRegex = /^http:\/\/(localhost|127\.0\.0\.1|10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|172\.(1[6-9]|2\d|3[0-1])\.\d+\.\d+):\d+$/; - - const herokuRegex = /^https:\/\/(?:homebrewery-pr-\d+\.herokuapp\.com|naturalcrit-pr-\d+\.herokuapp\.com)$/; // Matches any Heroku app - - if(!origin || allowedOrigins.includes(origin) || herokuRegex.test(origin) || (isLocalEnvironment && localNetworkRegex.test(origin))) { - callback(null, true); - } else { - console.log(origin, 'not allowed'); - callback(new Error('Not allowed by CORS, if you think this is an error, please contact us')); + const sanitizeBrew = (brew, accessType)=>{ + brew._id = undefined; + brew.__v = undefined; + if(accessType !== 'edit' && accessType !== 'shareAuthor') { + brew.editId = undefined; } - }, - methods : ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], - credentials : true, -}; + return brew; + }; -app.use(cors(corsOptions)); + app.set('trust proxy', 1 /* number of proxies between user and server */); -//Account Middleware -app.use((req, res, next)=>{ - if(req.cookies && req.cookies.nc_session){ - try { - req.account = jwt.decode(req.cookies.nc_session, config.get('secret')); + if(vite) { + app.use(vite.middlewares); + } + + app.use('/', serveCompressedStaticAssets('build')); + app.use(contentNegotiation); + app.use(bodyParser.json({ limit: '25mb' })); + app.use(cookieParser()); + app.use(forceSSL); + + + const corsOptions = { + origin : (origin, callback)=>{ + + const allowedOrigins = [ + 'https://homebrewery.naturalcrit.com', + 'https://www.naturalcrit.com', + 'https://naturalcrit-stage.herokuapp.com', + 'https://homebrewery-stage.herokuapp.com', + ]; + + const localNetworkRegex = /^http:\/\/(localhost|127\.0\.0\.1|10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|172\.(1[6-9]|2\d|3[0-1])\.\d+\.\d+):\d+$/; + + const herokuRegex = /^https:\/\/(?:homebrewery-pr-\d+\.herokuapp\.com|naturalcrit-pr-\d+\.herokuapp\.com)$/; // Matches any Heroku app + + if(!origin || allowedOrigins.includes(origin) || herokuRegex.test(origin) || (isLocalEnvironment && localNetworkRegex.test(origin))) { + callback(null, true); + } else { + console.log(origin, 'not allowed'); + callback(new Error('Not allowed by CORS, if you think this is an error, please contact us')); + } + }, + methods : ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], + credentials : true, + }; + + app.use(cors(corsOptions)); + + //Account Middleware + app.use((req, res, next)=>{ + if(req.cookies && req.cookies.nc_session){ + try { + req.account = jwt.decode(req.cookies.nc_session, config.get('secret')); //console.log("Just loaded up JWT from cookie:"); //console.log(req.account); - } catch (e){ - console.log(e); + } catch (e){ + console.log(e); + } } - } - req.config = { - google_client_id : config.get('google_client_id'), - google_client_secret : config.get('google_client_secret') - }; - return next(); -}); - -app.use(homebrewApi); -app.use(adminApi); -app.use(vaultApi); - -const welcomeText = fs.readFileSync('client/homebrew/pages/homePage/welcome_msg.md', 'utf8'); -const welcomeTextLegacy = fs.readFileSync('client/homebrew/pages/homePage/welcome_msg_legacy.md', 'utf8'); -const migrateText = fs.readFileSync('client/homebrew/pages/homePage/migrate.md', 'utf8'); -const changelogText = fs.readFileSync('changelog.md', 'utf8'); -const faqText = fs.readFileSync('faq.md', 'utf8'); - -String.prototype.replaceAll = function(s, r){return this.split(s).join(r);}; - -const defaultMetaTags = { - site_name : 'The Homebrewery - Make your Homebrew content look legit!', - title : 'The Homebrewery', - description : 'A NaturalCrit Tool for creating authentic Homebrews using Markdown.', - image : `${config.get('publicUrl')}/thumbnail.png`, - type : 'website' -}; - -//Robots.txt -app.get('/robots.txt', (req, res)=>{ - return res.sendFile(`robots.txt`, { root: process.cwd() }); -}); - -//Home page -app.get('/', (req, res, next)=>{ - req.brew = { - text : welcomeText, - renderer : 'V3', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'Homepage', - description : 'Homepage' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//Home page Legacy -app.get('/legacy', (req, res, next)=>{ - req.brew = { - text : welcomeTextLegacy, - renderer : 'legacy', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'Homepage (Legacy)', - description : 'Homepage' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//Legacy/Other Document -> v3 Migration Guide -app.get('/migrate', (req, res, next)=>{ - req.brew = { - text : migrateText, - renderer : 'V3', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'v3 Migration Guide', - description : 'A brief guide to converting Legacy documents to the v3 renderer.' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//Changelog page -app.get('/changelog', async (req, res, next)=>{ - req.brew = { - title : 'Changelog', - text : changelogText, - renderer : 'V3', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'Changelog', - description : 'Development changelog.' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//FAQ page -app.get('/faq', async (req, res, next)=>{ - req.brew = { - title : 'FAQ', - text : faqText, - renderer : 'V3', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'FAQ', - description : 'Frequently Asked Questions' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//Source page -app.get('/source/:id', asyncHandler(getBrew('share')), (req, res)=>{ - const { brew } = req; - - const replaceStrings = { '&': '&', '<': '<', '>': '>' }; - let text = brew.text; - for (const replaceStr in replaceStrings) { - text = text.replaceAll(replaceStr, replaceStrings[replaceStr]); - } - text = `
    ${text}
    `; - res.status(200).send(text); -}); - -//Download brew source page -app.get('/download/:id', asyncHandler(getBrew('share')), (req, res)=>{ - const { brew } = req; - sanitizeBrew(brew, 'share'); - const prefix = 'HB - '; - - const encodeRFC3986ValueChars = (str)=>{ - return ( - encodeURIComponent(str) - .replace(/[!'()*]/g, (char)=>{`%${char.charCodeAt(0).toString(16).toUpperCase()}`;}) - ); - }; - - let fileName = sanitizeFilename(`${prefix}${brew.title}`).replaceAll(' ', ''); - if(!fileName || !fileName.length) { fileName = `${prefix}-Untitled-Brew`; }; - res.set({ - 'Cache-Control' : 'no-cache', - 'Content-Type' : 'text/plain', - 'Content-Disposition' : `attachment; filename*=UTF-8''${encodeRFC3986ValueChars(fileName)}.txt` + req.config = { + google_client_id : config.get('google_client_id'), + google_client_secret : config.get('google_client_secret') + }; + return next(); }); - res.status(200).send(brew.text); -}); -//Serve brew metadata -app.get('/metadata/:id', asyncHandler(getBrew('share')), (req, res)=>{ - const { brew } = req; - sanitizeBrew(brew, 'share'); + app.use(homebrewApi); + app.use(adminApi(vite)); + app.use(vaultApi); - const fields = ['title', 'pageCount', 'description', 'authors', 'lang', + const welcomeText = fs.readFileSync('./client/homebrew/pages/homePage/welcome_msg.md', 'utf8'); + const welcomeTextLegacy = fs.readFileSync('./client/homebrew/pages/homePage/welcome_msg_legacy.md', 'utf8'); + const migrateText = fs.readFileSync('./client/homebrew/pages/homePage/migrate.md', 'utf8'); + const changelogText = fs.readFileSync('changelog.md', 'utf8'); + const faqText = fs.readFileSync('faq.md', 'utf8'); + + String.prototype.replaceAll = function(s, r){return this.split(s).join(r);}; + + const defaultMetaTags = { + site_name : 'The Homebrewery - Make your Homebrew content look legit!', + title : 'The Homebrewery', + description : 'A NaturalCrit Tool for creating authentic Homebrews using Markdown.', + image : `${config.get('publicUrl')}/thumbnail.png`, + type : 'website' + }; + + //Robots.txt + app.get('/robots.txt', (req, res)=>{ + return res.sendFile(`robots.txt`, { root: process.cwd() }); + }); + + //Home page + app.get('/', (req, res, next)=>{ + req.brew = { + text : welcomeText, + renderer : 'V3', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'Homepage', + description : 'Homepage' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //Home page Legacy + app.get('/legacy', (req, res, next)=>{ + req.brew = { + text : welcomeTextLegacy, + renderer : 'legacy', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'Homepage (Legacy)', + description : 'Homepage' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //Legacy/Other Document -> v3 Migration Guide + app.get('/migrate', (req, res, next)=>{ + req.brew = { + text : migrateText, + renderer : 'V3', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'v3 Migration Guide', + description : 'A brief guide to converting Legacy documents to the v3 renderer.' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //Changelog page + app.get('/changelog', async (req, res, next)=>{ + req.brew = { + title : 'Changelog', + text : changelogText, + renderer : 'V3', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'Changelog', + description : 'Development changelog.' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //FAQ page + app.get('/faq', async (req, res, next)=>{ + req.brew = { + title : 'FAQ', + text : faqText, + renderer : 'V3', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'FAQ', + description : 'Frequently Asked Questions' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //Source page + app.get('/source/:id', asyncHandler(getBrew('share')), (req, res)=>{ + const { brew } = req; + + const replaceStrings = { '&': '&', '<': '<', '>': '>' }; + let text = brew.text; + for (const replaceStr in replaceStrings) { + text = text.replaceAll(replaceStr, replaceStrings[replaceStr]); + } + text = `
    ${text}
    `; + res.status(200).send(text); + }); + + //Download brew source page + app.get('/download/:id', asyncHandler(getBrew('share')), (req, res)=>{ + const { brew } = req; + sanitizeBrew(brew, 'share'); + const prefix = 'HB - '; + + const encodeRFC3986ValueChars = (str)=>{ + return ( + encodeURIComponent(str) + .replace(/[!'()*]/g, (char)=>{`%${char.charCodeAt(0).toString(16).toUpperCase()}`;}) + ); + }; + + let fileName = sanitizeFilename(`${prefix}${brew.title}`).replaceAll(' ', ''); + if(!fileName || !fileName.length) { fileName = `${prefix}-Untitled-Brew`; }; + res.set({ + 'Cache-Control' : 'no-cache', + 'Content-Type' : 'text/plain', + 'Content-Disposition' : `attachment; filename*=UTF-8''${encodeRFC3986ValueChars(fileName)}.txt` + }); + res.status(200).send(brew.text); + }); + + //Serve brew metadata + app.get('/metadata/:id', asyncHandler(getBrew('share')), (req, res)=>{ + const { brew } = req; + sanitizeBrew(brew, 'share'); + + const fields = ['title', 'pageCount', 'description', 'authors', 'lang', 'published', 'views', 'shareId', 'createdAt', 'updatedAt', 'lastViewed', 'thumbnail', 'tags' - ]; + ]; - const metadata = fields.reduce((acc, field)=>{ + const metadata = fields.reduce((acc, field)=>{ if(brew[field] !== undefined) acc[field] = brew[field]; return acc; - }, {}); - res.status(200).json(metadata); -}); + }, {}); + res.status(200).json(metadata); + }); -//Serve brew styling -app.get('/css/:id', asyncHandler(getBrew('share')), (req, res)=>{getCSS(req, res);}); + //Serve brew styling + app.get('/css/:id', asyncHandler(getBrew('share')), (req, res)=>{getCSS(req, res);}); -//User Page -app.get('/user/:username', dbCheck, async (req, res, next)=>{ - const ownAccount = req.account && (req.account.username == req.params.username); + //User Page + app.get('/user/:username', dbCheck, async (req, res, next)=>{ + const ownAccount = req.account && (req.account.username == req.params.username); - req.ogMeta = { ...defaultMetaTags, - title : `${req.params.username}'s Collection`, - description : 'View my collection of homebrew on the Homebrewery.' + req.ogMeta = { ...defaultMetaTags, + title : `${req.params.username}'s Collection`, + description : 'View my collection of homebrew on the Homebrewery.' // type : could be 'profile'? - }; + }; - const fields = [ - 'googleId', - 'title', - 'pageCount', - 'description', - 'authors', - 'lang', - 'published', - 'views', - 'shareId', - 'editId', - 'createdAt', - 'updatedAt', - 'lastViewed', - 'thumbnail', - 'tags' - ]; + const fields = [ + 'googleId', + 'title', + 'pageCount', + 'description', + 'authors', + 'lang', + 'published', + 'views', + 'shareId', + 'editId', + 'createdAt', + 'updatedAt', + 'lastViewed', + 'thumbnail', + 'tags' + ]; - let brews = await HomebrewModel.getByUser(req.params.username, ownAccount, fields) + let brews = await HomebrewModel.getByUser(req.params.username, ownAccount, fields) .catch((err)=>{ console.log(err); }); - brews.forEach((brew)=>brew.stubbed = true); //All brews from MongoDB are "stubbed" + brews.forEach((brew)=>brew.stubbed = true); //All brews from MongoDB are "stubbed" - if(ownAccount && req?.account?.googleId){ - const auth = await GoogleActions.authCheck(req.account, res); - let googleBrews = await GoogleActions.listGoogleBrews(auth) + if(ownAccount && req?.account?.googleId){ + const auth = await GoogleActions.authCheck(req.account, res); + let googleBrews = await GoogleActions.listGoogleBrews(auth) .catch((err)=>{ console.error(err); }); - // If stub matches file from Google, use Google metadata over stub metadata - if(googleBrews && googleBrews.length > 0) { - for (const brew of brews.filter((brew)=>brew.googleId)) { - const match = googleBrews.findIndex((b)=>b.editId === brew.editId); - if(match !== -1) { - brew.googleId = googleBrews[match].googleId; - brew.pageCount = googleBrews[match].pageCount; - brew.renderer = googleBrews[match].renderer; - brew.version = googleBrews[match].version; - brew.webViewLink = googleBrews[match].webViewLink; - googleBrews.splice(match, 1); + // If stub matches file from Google, use Google metadata over stub metadata + if(googleBrews && googleBrews.length > 0) { + for (const brew of brews.filter((brew)=>brew.googleId)) { + const match = googleBrews.findIndex((b)=>b.editId === brew.editId); + if(match !== -1) { + brew.googleId = googleBrews[match].googleId; + brew.pageCount = googleBrews[match].pageCount; + brew.renderer = googleBrews[match].renderer; + brew.version = googleBrews[match].version; + brew.webViewLink = googleBrews[match].webViewLink; + googleBrews.splice(match, 1); + } } + + //Remaining unstubbed google brews display current user as author + googleBrews = googleBrews.map((brew)=>({ ...brew, authors: [req.account.username] })); + brews = _.concat(brews, googleBrews); } - - //Remaining unstubbed google brews display current user as author - googleBrews = googleBrews.map((brew)=>({ ...brew, authors: [req.account.username] })); - brews = _.concat(brews, googleBrews); } - } - req.brews = _.map(brews, (brew)=>{ + req.brews = _.map(brews, (brew)=>{ // Clean up brew data - brew.title = brew.title?.trim(); - brew.description = brew.description?.trim(); - return sanitizeBrew(brew, ownAccount ? 'edit' : 'share'); + brew.title = brew.title?.trim(); + brew.description = brew.description?.trim(); + return sanitizeBrew(brew, ownAccount ? 'edit' : 'share'); + }); + + return next(); }); - return next(); -}); + //Change author name on brews + app.put('/api/user/rename', dbCheck, async (req, res)=>{ + const { username, newUsername } = req.body; + const ownAccount = req.account && (req.account.username == newUsername); -//Change author name on brews -app.put('/api/user/rename', dbCheck, async (req, res)=>{ - const { username, newUsername } = req.body; - const ownAccount = req.account && (req.account.username == newUsername); + if(!username || !newUsername) + return res.status(400).json({ error: 'Username and newUsername are required.' }); + if(!ownAccount) + return res.status(403).json({ error: 'Must be logged in to change your username' }); + try { + const brews = await HomebrewModel.getByUser(username, true, ['authors']); + const renamePromises = brews.map(async (brew)=>{ + const updatedAuthors = brew.authors.map((author)=>author === username ? newUsername : author + ); + return HomebrewModel.updateOne( + { _id: brew._id }, + { $set: { authors: updatedAuthors } } + ); + }); + await Promise.all(renamePromises); - if(!username || !newUsername) - return res.status(400).json({ error: 'Username and newUsername are required.' }); - if(!ownAccount) - return res.status(403).json({ error: 'Must be logged in to change your username' }); - try { - const brews = await HomebrewModel.getByUser(username, true, ['authors']); - const renamePromises = brews.map(async (brew)=>{ - const updatedAuthors = brew.authors.map((author)=>author === username ? newUsername : author - ); - return HomebrewModel.updateOne( - { _id: brew._id }, - { $set: { authors: updatedAuthors } } - ); - }); - await Promise.all(renamePromises); - - return res.json({ success: true, message: `Brews for ${username} renamed to ${newUsername}.` }); - } catch (error) { - console.error('Error renaming brews:', error); - return res.status(500).json({ error: 'Failed to rename brews.' }); - } -}); - -//Edit Page -app.get('/edit/:id', asyncHandler(getBrew('edit')), asyncHandler(async(req, res, next)=>{ - req.brew = req.brew.toObject ? req.brew.toObject() : req.brew; - - req.userThemes = await(getUsersBrewThemes(req.account?.username)); - - req.ogMeta = { ...defaultMetaTags, - title : req.brew.title || 'Untitled Brew', - description : req.brew.description || 'No description.', - image : req.brew.thumbnail || defaultMetaTags.image, - locale : req.brew.lang, - type : 'article' - }; - - sanitizeBrew(req.brew, 'edit'); - splitTextStyleAndMetadata(req.brew); - res.header('Cache-Control', 'no-cache, no-store'); //reload the latest saved brew when pressing back button, not the cached version before save. - return next(); -})); - -//New Page from ID -app.get('/new/:id', asyncHandler(getBrew('share')), asyncHandler(async(req, res, next)=>{ - sanitizeBrew(req.brew, 'share'); - splitTextStyleAndMetadata(req.brew); - const brew = { - shareId : req.brew.shareId, - title : `CLONE - ${req.brew.title}`, - text : req.brew.text, - style : req.brew.style, - renderer : req.brew.renderer, - theme : req.brew.theme, - tags : req.brew.tags, - snippets : req.brew.snippets - }; - req.brew = _.defaults(brew, DEFAULT_BREW); - - req.userThemes = await(getUsersBrewThemes(req.account?.username)); - - req.ogMeta = { ...defaultMetaTags, - title : 'New', - description : 'Start crafting your homebrew on the Homebrewery!' - }; - - return next(); -})); - -//New Page -app.get('/new', asyncHandler(async(req, res, next)=>{ - req.userThemes = await(getUsersBrewThemes(req.account?.username)); - - req.ogMeta = { ...defaultMetaTags, - title : 'New', - description : 'Start crafting your homebrew on the Homebrewery!' - }; - - return next(); -})); - -//Share Page -app.get('/share/:id', dbCheck, asyncHandler(getBrew('share')), asyncHandler(async (req, res, next)=>{ - const { brew } = req; - req.ogMeta = { ...defaultMetaTags, - title : `${req.brew.title || 'Untitled Brew'} - ${req.brew.authors[0] || 'No author.'}`, - description : req.brew.description || 'No description.', - image : req.brew.thumbnail || defaultMetaTags.image, - type : 'article' - }; - - // increase visitor view count, do not include visits by author(s) - if(!brew.authors.includes(req.account?.username)){ - if(req.params.id.length > 12 && !brew._id) { - const googleId = brew.googleId; - const shareId = brew.shareId; - await GoogleActions.increaseView(googleId, shareId, 'share', brew) - .catch((err)=>{next(err);}); - } else { - await HomebrewModel.increaseView({ shareId: brew.shareId }); + return res.json({ success: true, message: `Brews for ${username} renamed to ${newUsername}.` }); + } catch (error) { + console.error('Error renaming brews:', error); + return res.status(500).json({ error: 'Failed to rename brews.' }); } - }; + }); - brew.authors.includes(req.account?.username) ? sanitizeBrew(req.brew, 'shareAuthor') : sanitizeBrew(req.brew, 'share'); - splitTextStyleAndMetadata(req.brew); - return next(); -})); + //Edit Page + app.get('/edit/:id', asyncHandler(getBrew('edit')), asyncHandler(async(req, res, next)=>{ + req.brew = req.brew.toObject ? req.brew.toObject() : req.brew; -//Account Page -app.get('/account', dbCheck, asyncHandler(async (req, res, next)=>{ - const data = {}; - data.title = 'Account Information Page'; + req.userThemes = await(getUsersBrewThemes(req.account?.username)); - if(!req.account) { - res.set('WWW-Authenticate', 'Bearer realm="Authorization Required"'); - const error = new Error('No valid account'); - error.status = 401; - error.HBErrorCode = '50'; - error.page = data.title; - return next(error); - }; + req.ogMeta = { ...defaultMetaTags, + title : req.brew.title || 'Untitled Brew', + description : req.brew.description || 'No description.', + image : req.brew.thumbnail || defaultMetaTags.image, + locale : req.brew.lang, + type : 'article' + }; - let auth; - let googleCount = []; - if(req.account) { - if(req.account.googleId) { - auth = await GoogleActions.authCheck(req.account, res, false); + sanitizeBrew(req.brew, 'edit'); + splitTextStyleAndMetadata(req.brew); + res.header('Cache-Control', 'no-cache, no-store'); //reload the latest saved brew when pressing back button, not the cached version before save. + return next(); + })); - googleCount = await GoogleActions.listGoogleBrews(auth) + //New Page from ID + app.get('/new/:id', asyncHandler(getBrew('share')), asyncHandler(async(req, res, next)=>{ + sanitizeBrew(req.brew, 'share'); + splitTextStyleAndMetadata(req.brew); + const brew = { + shareId : req.brew.shareId, + title : `CLONE - ${req.brew.title}`, + text : req.brew.text, + style : req.brew.style, + renderer : req.brew.renderer, + theme : req.brew.theme, + tags : req.brew.tags, + snippets : req.brew.snippets + }; + req.brew = _.defaults(brew, DEFAULT_BREW); + + req.userThemes = await(getUsersBrewThemes(req.account?.username)); + + req.ogMeta = { ...defaultMetaTags, + title : 'New', + description : 'Start crafting your homebrew on the Homebrewery!' + }; + + return next(); + })); + + //New Page + app.get('/new', asyncHandler(async(req, res, next)=>{ + req.userThemes = await(getUsersBrewThemes(req.account?.username)); + + req.ogMeta = { ...defaultMetaTags, + title : 'New', + description : 'Start crafting your homebrew on the Homebrewery!' + }; + + return next(); + })); + + //Share Page + app.get('/share/:id', dbCheck, asyncHandler(getBrew('share')), asyncHandler(async (req, res, next)=>{ + const { brew } = req; + req.ogMeta = { ...defaultMetaTags, + title : `${req.brew.title || 'Untitled Brew'} - ${req.brew.authors[0] || 'No author.'}`, + description : req.brew.description || 'No description.', + image : req.brew.thumbnail || defaultMetaTags.image, + type : 'article' + }; + + // increase visitor view count, do not include visits by author(s) + if(!brew.authors.includes(req.account?.username)){ + if(req.params.id.length > 12 && !brew._id) { + const googleId = brew.googleId; + const shareId = brew.shareId; + await GoogleActions.increaseView(googleId, shareId, 'share', brew) + .catch((err)=>{next(err);}); + } else { + await HomebrewModel.increaseView({ shareId: brew.shareId }); + } + }; + + brew.authors.includes(req.account?.username) ? sanitizeBrew(req.brew, 'shareAuthor') : sanitizeBrew(req.brew, 'share'); + splitTextStyleAndMetadata(req.brew); + return next(); + })); + + //Account Page + app.get('/account', dbCheck, asyncHandler(async (req, res, next)=>{ + const data = {}; + data.title = 'Account Information Page'; + + if(!req.account) { + res.set('WWW-Authenticate', 'Bearer realm="Authorization Required"'); + const error = new Error('No valid account'); + error.status = 401; + error.HBErrorCode = '50'; + error.page = data.title; + return next(error); + }; + + let auth; + let googleCount = []; + if(req.account) { + if(req.account.googleId) { + auth = await GoogleActions.authCheck(req.account, res, false); + + googleCount = await GoogleActions.listGoogleBrews(auth) .catch((err)=>{ console.error(err); }); - } + } - const query = { authors: req.account.username, googleId: { $exists: false } }; - const mongoCount = await HomebrewModel.countDocuments(query) + const query = { authors: req.account.username, googleId: { $exists: false } }; + const mongoCount = await HomebrewModel.countDocuments(query) .catch((err)=>{ console.log(err); return 0; }); - data.accountDetails = { - username : req.account.username, - issued : req.account.issued, - googleId : Boolean(req.account.googleId), - authCheck : Boolean(req.account.googleId && auth?.credentials.access_token), - mongoCount : mongoCount, - googleCount : googleCount?.length + data.accountDetails = { + username : req.account.username, + issued : req.account.issued, + googleId : Boolean(req.account.googleId), + authCheck : Boolean(req.account.googleId && auth?.credentials.access_token), + mongoCount : mongoCount, + googleCount : googleCount?.length + }; + } + + req.brew = data; + + req.ogMeta = { ...defaultMetaTags, + title : `Account Page`, + description : null }; - } - req.brew = data; + return next(); + })); - req.ogMeta = { ...defaultMetaTags, - title : `Account Page`, - description : null - }; - - return next(); -})); - -// Local only -if(isLocalEnvironment){ + // Local only + if(isLocalEnvironment){ // Login - app.post('/local/login', (req, res)=>{ - const username = req.body.username; - if(!username) return; + app.post('/local/login', (req, res)=>{ + const username = req.body.username; + if(!username) return; - const payload = jwt.encode({ username: username, issued: new Date }, config.get('secret')); - return res.json(payload); - }); -} - -// Add Static Local Paths -app.use('/staticImages', express.static(config.get('hb_images') && fs.existsSync(config.get('hb_images')) ? config.get('hb_images') :'staticImages')); -app.use('/staticFonts', express.static(config.get('hb_fonts') && fs.existsSync(config.get('hb_fonts')) ? config.get('hb_fonts'):'staticFonts')); - -//Vault Page -app.get('/vault', asyncHandler(async(req, res, next)=>{ - req.ogMeta = { ...defaultMetaTags, - title : 'The Vault', - description : 'Search for Brews' - }; - return next(); -})); - -//Send rendered page -app.use(asyncHandler(async (req, res, next)=>{ - if(!req.route) return res.redirect('/'); // Catch-all for invalid routes - - const page = await renderPage(req, res); - if(!page) return; - res.send(page); -})); - -//Render the page -const renderPage = async (req, res)=>{ - // Create configuration object - const configuration = { - local : isLocalEnvironment, - publicUrl : config.get('publicUrl') ?? '', - baseUrl : `${req.protocol}://${req.get('host')}`, - environment : nodeEnv, - deployment : config.get('heroku_app_name') ?? '' - }; - const props = { - version : version, - url : req.customUrl || req.originalUrl, - brew : req.brew, - brews : req.brews, - googleBrews : req.googleBrews, - account : req.account, - config : configuration, - ogMeta : req.ogMeta, - userThemes : req.userThemes - }; - const title = req.brew ? req.brew.title : ''; - const page = await templateFn('homebrew', title, props) - .catch((err)=>{ - console.log(err); + const payload = jwt.encode({ username: username, issued: new Date }, config.get('secret')); + return res.json(payload); }); - return page; -}; - -//v=====----- Error-Handling Middleware -----=====v// -//Format Errors as plain objects so all fields will appear in the string sent -const formatErrors = (key, value)=>{ - if(value instanceof Error) { - const error = {}; - Object.getOwnPropertyNames(value).forEach(function (key) { - error[key] = value[key]; - }); - return error; } - return value; -}; -const getPureError = (error)=>{ - return JSON.parse(JSON.stringify(error, formatErrors)); -}; + // Add Static Local Paths + app.use('/staticImages', express.static(config.get('hb_images') && fs.existsSync(config.get('hb_images')) ? config.get('hb_images') :'staticImages')); + app.use('/staticFonts', express.static(config.get('hb_fonts') && fs.existsSync(config.get('hb_fonts')) ? config.get('hb_fonts'):'staticFonts')); -app.use(async (err, req, res, next)=>{ - err.originalUrl = req.originalUrl; - console.error(err); + //Vault Page + app.get('/vault', asyncHandler(async(req, res, next)=>{ + req.ogMeta = { ...defaultMetaTags, + title : 'The Vault', + description : 'Search for Brews' + }; + return next(); + })); - if(err.originalUrl?.startsWith('/api')) { + //Send rendered page + app.use(asyncHandler(async (req, res, next)=>{ + if(!req.route) return res.redirect('/'); // Catch-all for invalid routes + + const page = await renderPage(req, res); + if(!page) return; + res.send(page); + })); + + //Render the page + const renderPage = async (req, res)=>{ + + // Create configuration object + const configuration = { + local : isLocalEnvironment, + publicUrl : config.get('publicUrl') ?? '', + baseUrl : `${req.protocol}://${req.get('host')}`, + environment : nodeEnv, + deployment : config.get('heroku_app_name') ?? '' + }; + const props = { + version : version, + url : req.customUrl || req.originalUrl, + brew : req.brew, + brews : req.brews, + googleBrews : req.googleBrews, + account : req.account, + config : configuration, + ogMeta : req.ogMeta, + userThemes : req.userThemes + }; + + const ogTags = []; + const ogMeta = req.ogMeta ?? {}; + Object.entries(ogMeta).forEach(([key, value])=>{ + if(!value) return; + const tag = ``; + ogTags.push(tag); + }); + const ogMetaTags = ogTags.join('\n'); + + const htmlPath = isProd ? path.resolve('build', 'index.html') : path.resolve('index.html'); + let html = fs.readFileSync(htmlPath, 'utf-8'); + + if(!isProd && vite?.transformIndexHtml) { + html = await vite.transformIndexHtml(req.originalUrl, html); + } + + html = html.replace( + '', + `\n\n${ogMetaTags}` + ); + + return html; + }; + + //v=====----- Error-Handling Middleware -----=====v// + //Format Errors as plain objects so all fields will appear in the string sent + const formatErrors = (key, value)=>{ + if(value instanceof Error) { + const error = {}; + Object.getOwnPropertyNames(value).forEach(function (key) { + error[key] = value[key]; + }); + return error; + } + return value; + }; + + const getPureError = (error)=>{ + return JSON.parse(JSON.stringify(error, formatErrors)); + }; + + app.use(async (err, req, res, next)=>{ + err.originalUrl = req.originalUrl; + console.error(err); + + if(err.originalUrl?.startsWith('/api')) { // console.log('API error'); - res.status(err.status || err.response?.status || 500).send(err); - return; - } + res.status(err.status || err.response?.status || 500).send(err); + return; + } - // console.log('non-API error'); - const status = err.status || err.code || 500; + // console.log('non-API error'); + const status = err.status || err.code || 500; - req.ogMeta = { ...defaultMetaTags, - title : 'Error Page', - description : 'Something went wrong!' - }; - req.brew = { - ...err, - title : 'Error - Something went wrong!', - text : err.errors?.map((error)=>{return error.message;}).join('\n\n') || err.message || 'Unknown error!', - status : status, - HBErrorCode : err.HBErrorCode ?? '00', - pureError : getPureError(err) - }; - req.customUrl= '/error'; + req.ogMeta = { ...defaultMetaTags, + title : 'Error Page', + description : 'Something went wrong!' + }; + req.brew = { + ...err, + title : 'Error - Something went wrong!', + text : err.errors?.map((error)=>{return error.message;}).join('\n\n') || err.message || 'Unknown error!', + status : status, + HBErrorCode : err.HBErrorCode ?? '00', + pureError : getPureError(err) + }; + req.customUrl= '/error'; - const page = await renderPage(req, res); - if(!page) return; - res.send(page); -}); + const page = await renderPage(req, res); + if(!page) return; + res.send(page); + }); -app.use((req, res)=>{ - if(!res.headersSent) { - console.error('Headers have not been sent, responding with a server error.', req.url); - res.status(500).send('An error occurred and the server did not send a response. The error has been logged, please note the time this occurred and report this issue.'); - } -}); -//^=====--------------------------------------=====^// + app.use((req, res)=>{ + if(!res.headersSent) { + console.error('Headers have not been sent, responding with a server error.', req.url); + res.status(500).send('An error occurred and the server did not send a response. The error has been logged, please note the time this occurred and report this issue.'); + } + }); + //^=====--------------------------------------=====^// -export default app; + return app; +} diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 4d4f5a911..bb8d76ce5 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -481,7 +481,7 @@ const api = { await HomebrewModel.deleteOne({ editId: id }); return next(); } - throw(err); + throw (err); } let brew = req.brew; diff --git a/shared/helpers.js b/shared/helpers.js index adf5b889a..8177aa7a9 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -19,7 +19,7 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=nul userSnippets.push({ name : snippetName, icon : '', - gen : snipSplit[snips + 1], + gen : snipSplit[snips + 1].replace(/\n$/, ''), }); } } @@ -44,7 +44,7 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=nul if(snippetName.length != 0) { const subSnip = { name : snippetName, - gen : snipSplit[snips + 1], + gen : snipSplit[snips + 1].replace(/\n$/, ''), }; // if(full) subSnip.icon = ''; userSnippets.push(subSnip); diff --git a/shared/markdown.js b/shared/markdown.js index adb058042..09a6b37e3 100644 --- a/shared/markdown.js +++ b/shared/markdown.js @@ -1,4 +1,4 @@ -/* eslint-disable max-depth */ + /* eslint-disable max-lines */ import _ from 'lodash'; import { marked as Marked } from 'marked'; diff --git a/shared/naturalcrit/styles/core.less b/shared/naturalcrit/styles/core.less index 02db5db18..3ef75144d 100644 --- a/shared/naturalcrit/styles/core.less +++ b/shared/naturalcrit/styles/core.less @@ -1,16 +1,16 @@ -@import 'naturalcrit/styles/reset.less'; -//@import 'naturalcrit/styles/elements.less'; -@import 'naturalcrit/styles/animations.less'; -@import 'naturalcrit/styles/colors.less'; -@import 'naturalcrit/styles/tooltip.less'; +@import './reset.less'; +//@import './elements.less'; +@import './animations.less'; +@import './colors.less'; +@import './tooltip.less'; @font-face { font-family : 'CodeLight'; - src : data-uri('naturalcrit/styles/CODE Light.otf') format('opentype'); + src : url('./CODE Light.otf') format('opentype'); } @font-face { font-family : 'CodeBold'; - src : data-uri('naturalcrit/styles/CODE Bold.otf') format('opentype'); + src : url('./CODE Bold.otf') format('opentype'); } html,body, #reactRoot { height : 100vh; diff --git a/shared/naturalcrit/styles/tooltip.less b/shared/naturalcrit/styles/tooltip.less index b21439486..3150aa789 100644 --- a/shared/naturalcrit/styles/tooltip.less +++ b/shared/naturalcrit/styles/tooltip.less @@ -3,18 +3,23 @@ @arrowSize : 6px; @arrowPosition : 18px; [data-tooltip] { + position:relative; .tooltip(attr(data-tooltip)); } [data-tooltip-top] { + position:relative; .tooltipTop(attr(data-tooltip-top)); } [data-tooltip-bottom] { + position:relative; .tooltipBottom(attr(data-tooltip-bottom)); } [data-tooltip-left] { + position:relative; .tooltipLeft(attr(data-tooltip-left)); } [data-tooltip-right] { + position:relative; .tooltipRight(attr(data-tooltip-right)); } .tooltip(@content) { @@ -30,6 +35,7 @@ &::before, &::after { bottom : 100%; left : 50%; + translate: -50% 0; } &:hover::after, &:hover::before, &:focus::after, &:focus::before { .transform(translateY(-(@arrowSize + 2))); @@ -45,6 +51,7 @@ &::before, &::after { top : 100%; left : 50%; + translate: -50% 0; } &:hover::after, &:hover::before, &:focus::after, &:focus::before { .transform(translateY(@arrowSize + 2)); @@ -57,7 +64,10 @@ margin-bottom : -@arrowSize; border-left-color : @tooltipColor; } - &::after { margin-bottom : -14px;} + &::after { + margin-bottom : -14px; + max-width : 50ch; + } &::before, &::after { right : 100%; bottom : 50%; @@ -73,10 +83,14 @@ margin-left : -@arrowSize * 2; border-right-color : @tooltipColor; } - &::after { margin-bottom : -14px;} + &::after { + margin-bottom : -14px; + max-width : 50ch; + } &::before, &::after { - bottom : 50%; + top : 50%; left : 100%; + translate:0 -50%; } &:hover::after, &:hover::before, &:focus::after, &:focus::before { .transform(translateX(@arrowSize + 2)); @@ -106,9 +120,12 @@ font-size : 12px; line-height : 12px; color : white; - white-space : nowrap; content : @content; background : @tooltipColor; + max-width : 60ch; + width :max-content; + word-break : break-word; + overflow-wrap : break-word; } &:hover::before, &:hover::after { visibility : visible; diff --git a/tests/html/safeHTML.test.js b/tests/html/safeHTML.test.js index 208101f9a..0b5b4c169 100644 --- a/tests/html/safeHTML.test.js +++ b/tests/html/safeHTML.test.js @@ -1,6 +1,6 @@ import globalJsdom from 'jsdom-global'; globalJsdom(); -import { safeHTML } from '../../client/homebrew/brewRenderer/safeHTML'; +import safeHTML from '../../client/homebrew/brewRenderer/safeHTML'; test('Exit if no document', function() { const doc = document; diff --git a/tests/markdown/basic.test.js b/tests/markdown/basic.test.js index ddceb9197..f2405d0d8 100644 --- a/tests/markdown/basic.test.js +++ b/tests/markdown/basic.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; test('Processes the markdown within an HTML block if its just a class wrapper', function() { const source = '
    *Bold text*
    '; diff --git a/tests/markdown/definition-lists.test.js b/tests/markdown/definition-lists.test.js index 12499d559..35ad12ef7 100644 --- a/tests/markdown/definition-lists.test.js +++ b/tests/markdown/definition-lists.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; describe('Inline Definition Lists', ()=>{ test('No Term 1 Definition', function() { diff --git a/tests/markdown/emojis.test.js b/tests/markdown/emojis.test.js index 5f0e102c9..072de10f9 100644 --- a/tests/markdown/emojis.test.js +++ b/tests/markdown/emojis.test.js @@ -1,4 +1,4 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; import dedent from 'dedent'; // Marked.js adds line returns after closing tags on some default tokens. diff --git a/tests/markdown/hard-breaks.test.js b/tests/markdown/hard-breaks.test.js index 068b2053a..1f48f8f1e 100644 --- a/tests/markdown/hard-breaks.test.js +++ b/tests/markdown/hard-breaks.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; describe('Hard Breaks', ()=>{ test('Single Break', function() { diff --git a/tests/markdown/mustache-syntax.test.js b/tests/markdown/mustache-syntax.test.js index 8562ae412..95ca2f58d 100644 --- a/tests/markdown/mustache-syntax.test.js +++ b/tests/markdown/mustache-syntax.test.js @@ -1,7 +1,7 @@ /* eslint-disable max-lines */ import dedent from 'dedent'; -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; // Marked.js adds line returns after closing tags on some default tokens. // This removes those line returns for comparison sake. diff --git a/tests/markdown/non-breaking-spaces.test.js b/tests/markdown/non-breaking-spaces.test.js index 9da59b047..731d0546e 100644 --- a/tests/markdown/non-breaking-spaces.test.js +++ b/tests/markdown/non-breaking-spaces.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; describe('Non-Breaking Spaces Interactions', ()=>{ test('I am actually a single-line definition list!', function() { diff --git a/tests/markdown/paragraph-justification.test.js b/tests/markdown/paragraph-justification.test.js index f5a5b12ab..6ce454623 100644 --- a/tests/markdown/paragraph-justification.test.js +++ b/tests/markdown/paragraph-justification.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; describe('Justification', ()=>{ test('Left Justify', function() { diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js index 49cd333c8..884553703 100644 --- a/tests/markdown/variables.test.js +++ b/tests/markdown/variables.test.js @@ -1,7 +1,7 @@ /* eslint-disable max-lines */ import dedent from 'dedent'; -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; // Marked.js adds line returns after closing tags on some default tokens. // This removes those line returns for comparison sake. diff --git a/tests/routes/static-pages.test.js b/tests/routes/static-pages.test.js index ebfa48dd4..2741b8d70 100644 --- a/tests/routes/static-pages.test.js +++ b/tests/routes/static-pages.test.js @@ -1,27 +1,32 @@ import supertest from 'supertest'; -import HBApp from 'app.js'; +import createApp from '../../server/app.js'; -// Mimic https responses to avoid being redirected all the time -const app = supertest.agent(HBApp).set('X-Forwarded-Proto', 'https'); +let app; +let request; + +beforeAll(async ()=>{ + app = await createApp(); + request = supertest.agent(app).set('X-Forwarded-Proto', 'https'); +}); describe('Tests for static pages', ()=>{ - it('Home page works', ()=>{ - return app.get('/').expect(200); + it('Home page works', async ()=>{ + await request.get('/').expect(200); }); - it('Home page legacy works', ()=>{ - return app.get('/legacy').expect(200); + it('Home page legacy works', async ()=>{ + await request.get('/legacy').expect(200); }); - it('Changelog page works', ()=>{ - return app.get('/changelog').expect(200); + it('Changelog page works', async ()=>{ + await request.get('/changelog').expect(200); }); - it('FAQ page works', ()=>{ - return app.get('/faq').expect(200); + it('FAQ page works', async ()=>{ + await request.get('/faq').expect(200); }); - it('robots.txt works', ()=>{ - return app.get('/robots.txt').expect(200); + it('robots.txt works', async ()=>{ + await request.get('/robots.txt').expect(200); }); -}); +}); \ No newline at end of file diff --git a/themes/Legacy/5ePHB/snippets.js b/themes/Legacy/5ePHB/snippets.js index c5a864e89..5bf74b4ca 100644 --- a/themes/Legacy/5ePHB/snippets.js +++ b/themes/Legacy/5ePHB/snippets.js @@ -1,12 +1,12 @@ /* eslint-disable max-lines */ -import MagicGen from './snippets/magic.gen.js'; +import MagicGen from './snippets/magic.gen.js'; import ClassTableGen from './snippets/classtable.gen.js'; import MonsterBlockGen from './snippets/monsterblock.gen.js'; import ClassFeatureGen from './snippets/classfeature.gen.js'; import CoverPageGen from './snippets/coverpage.gen.js'; import TableOfContentsGen from './snippets/tableOfContents.gen.js'; -import dedent from 'dedent'; +import dedent from 'dedent'; export default [ @@ -40,7 +40,7 @@ export default [ icon : 'fas fa-image', gen : [ '', 'Credit: Kyounghwan Kim' ].join('\n') @@ -50,7 +50,7 @@ export default [ icon : 'fas fa-tree', gen : [ '' ].join('\n') }, diff --git a/themes/Legacy/5ePHB/snippets/classfeature.gen.js b/themes/Legacy/5ePHB/snippets/classfeature.gen.js index b92d527f9..70085d647 100644 --- a/themes/Legacy/5ePHB/snippets/classfeature.gen.js +++ b/themes/Legacy/5ePHB/snippets/classfeature.gen.js @@ -1,6 +1,6 @@ import _ from 'lodash'; -export default function(classname){ +function classFeatureGen(classname) { classname = _.sample(['archivist', 'fancyman', 'linguist', 'fletcher', 'notary', 'berserker-typist', 'fishmongerer', 'manicurist', 'haberdasher', 'concierge']); @@ -49,4 +49,6 @@ export default function(classname){ `- ${_.sample(['10 lint fluffs', '1 button', 'a cherished lost sock'])}`, '\n\n\n' ].join('\n'); -}; +} + +export default classFeatureGen; diff --git a/themes/Legacy/5ePHB/snippets/coverpage.gen.js b/themes/Legacy/5ePHB/snippets/coverpage.gen.js index 0cd0e50d5..9c2de2943 100644 --- a/themes/Legacy/5ePHB/snippets/coverpage.gen.js +++ b/themes/Legacy/5ePHB/snippets/coverpage.gen.js @@ -98,7 +98,7 @@ const subtitles = [ ]; -export default ()=>{ +function coverPageGen() { return ``); + return null; + }, +}; + +export const Inject = ({ tag, children, ...props })=>{ + useEffect(()=>{ + injectTag(tag, props, children); + }, []); + return null; +}; + +export const generate = ()=>Object.values(NamedTags).concat(UnnamedTags).join('\n'); + +export const flush = ()=>{ + NamedTags = {}; + UnnamedTags = []; +}; + +export const Meta = HeadComponents.Meta; + +export default { + Inject, + ...HeadComponents, + generate, + flush, +};