+ const snippetGroup = `snippetGroup snippetBarButton ${this.props.snippets.length === 0 ? 'disabledSnippets' : ''}`;
+ return
{this.props.groupName}
diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less
index 7d56dc718..a0691f8b6 100644
--- a/client/homebrew/editor/snippetbar/snippetbar.less
+++ b/client/homebrew/editor/snippetbar/snippetbar.less
@@ -14,15 +14,15 @@
.snippets {
display : flex;
justify-content : flex-start;
- min-width : 327.58px;
+ min-width : 432.18px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied
}
.editors {
display : flex;
justify-content : flex-end;
- min-width : 225px;
+ min-width : 250px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied
- &:only-child { margin-left : auto;min-width:unset;}
+ &:only-child {min-width : unset; margin-left : auto;}
>div {
display : flex;
@@ -39,9 +39,7 @@
text-align : center;
cursor : pointer;
- &.editorTool:not(.active) {
- cursor:not-allowed;
- }
+ &.editorTool:not(.active) { cursor : not-allowed; }
&:hover,&.selected { background-color : #999999; }
&.text {
@@ -53,6 +51,9 @@
&.meta {
.tooltipLeft('Properties');
}
+ &.snip {
+ .tooltipLeft('Snippets');
+ }
&.undo {
.tooltipLeft('Undo');
font-size : 0.75em;
@@ -151,9 +152,9 @@
position : absolute;
top : 100%;
z-index : 1000;
+ visibility : hidden;
padding : 0px;
margin-left : -5px;
- visibility : hidden;
background-color : #DDDDDD;
.snippet {
position : relative;
@@ -228,8 +229,15 @@
}
}
}
+ .disabledSnippets {
+ color: grey;
+ cursor: not-allowed;
+
+ &:hover { background-color: #DDDDDD;}
+ }
+
}
-@container editor (width < 553px) {
+@container editor (width < 683px) {
.snippetBar {
.editors {
flex : 1;
diff --git a/client/homebrew/editor/tagInput/tagInput.jsx b/client/homebrew/editor/tagInput/tagInput.jsx
index 816541167..d60e23b1b 100644
--- a/client/homebrew/editor/tagInput/tagInput.jsx
+++ b/client/homebrew/editor/tagInput/tagInput.jsx
@@ -3,43 +3,43 @@ const React = require('react');
const { useState, useEffect } = React;
const _ = require('lodash');
-const TagInput = ({ unique = true, values = [], ...props }) => {
+const TagInput = ({ unique = true, values = [], ...props })=>{
const [tempInputText, setTempInputText] = useState('');
- const [tagList, setTagList] = useState(values.map((value) => ({ value, editing: false })));
+ const [tagList, setTagList] = useState(values.map((value)=>({ value, editing: false })));
useEffect(()=>{
- handleChange(tagList.map((context)=>context.value))
- }, [tagList])
+ handleChange(tagList.map((context)=>context.value));
+ }, [tagList]);
const handleChange = (value)=>{
props.onChange({
target : { value }
- })
+ });
};
- const handleInputKeyDown = ({ evt, value, index, options = {} }) => {
- if (_.includes(['Enter', ','], evt.key)) {
+ const handleInputKeyDown = ({ evt, value, index, options = {} })=>{
+ if(_.includes(['Enter', ','], evt.key)) {
evt.preventDefault();
submitTag(evt.target.value, value, index);
- if (options.clear) {
+ if(options.clear) {
setTempInputText('');
}
}
};
- const submitTag = (newValue, originalValue, index) => {
- setTagList((prevContext) => {
+ const submitTag = (newValue, originalValue, index)=>{
+ setTagList((prevContext)=>{
// remove existing tag
if(newValue === null){
return [...prevContext].filter((context, i)=>i !== index);
}
// add new tag
if(originalValue === null){
- return [...prevContext, { value: newValue, editing: false }]
+ return [...prevContext, { value: newValue, editing: false }];
}
// update existing tag
- return prevContext.map((context, i) => {
- if (i === index) {
+ return prevContext.map((context, i)=>{
+ if(i === index) {
return { ...context, value: newValue, editing: false };
}
return context;
@@ -47,10 +47,10 @@ const TagInput = ({ unique = true, values = [], ...props }) => {
});
};
- const editTag = (index) => {
- setTagList((prevContext) => {
- return prevContext.map((context, i) => {
- if (i === index) {
+ const editTag = (index)=>{
+ setTagList((prevContext)=>{
+ return prevContext.map((context, i)=>{
+ if(i === index) {
return { ...context, editing: true };
}
return { ...context, editing: false };
@@ -58,25 +58,25 @@ const TagInput = ({ unique = true, values = [], ...props }) => {
});
};
- const renderReadTag = (context, index) => {
+ const renderReadTag = (context, index)=>{
return (
editTag(index)}>
+ onClick={()=>editTag(index)}>
{context.value}
- {evt.stopPropagation(); submitTag(null, context.value, index)}}>
+ {evt.stopPropagation(); submitTag(null, context.value, index);}}>
);
};
- const renderWriteTag = (context, index) => {
+ const renderWriteTag = (context, index)=>{
return (
handleInputKeyDown({evt, value: context.value, index: index})}
- autoFocus
+ defaultValue={context.value}
+ onKeyDown={(evt)=>handleInputKeyDown({ evt, value: context.value, index: index })}
+ autoFocus
/>
);
};
@@ -86,7 +86,7 @@ const TagInput = ({ unique = true, values = [], ...props }) => {
{props.label}
- {tagList.map((context, index) => { return context.editing ? renderWriteTag(context, index) : renderReadTag(context, index); })}
+ {tagList.map((context, index)=>{ return context.editing ? renderWriteTag(context, index) : renderReadTag(context, index); })}
{
className='value'
placeholder={props.placeholder}
value={tempInputText}
- onChange={(e) => setTempInputText(e.target.value)}
- onKeyDown={(evt) => handleInputKeyDown({ evt, value: null, options: { clear: true } })}
+ onChange={(e)=>setTempInputText(e.target.value)}
+ onKeyDown={(evt)=>handleInputKeyDown({ evt, value: null, options: { clear: true } })}
/>
diff --git a/client/homebrew/homebrew.less b/client/homebrew/homebrew.less
index 828de796f..e265c2941 100644
--- a/client/homebrew/homebrew.less
+++ b/client/homebrew/homebrew.less
@@ -1,36 +1,32 @@
@import 'naturalcrit/styles/core.less';
-.homebrew{
+.homebrew {
height : 100%;
- .sitePage{
+ .sitePage {
display : flex;
- height : 100%;
- background-color : @steel;
flex-direction : column;
+ height : 100%;
overflow-y : hidden;
- .content{
+ background-color : @steel;
+ .content {
position : relative;
- height : calc(~"100% - 29px"); //Navbar height
flex : auto;
+ height : calc(~'100% - 29px'); //Navbar height
overflow-y : hidden;
}
&.listPage .content {
overflow-y : scroll;
&::-webkit-scrollbar {
- width: 20px;
- &:horizontal{
- height: 20px;
- width:auto;
+ width : 20px;
+ &:horizontal {
+ width : auto;
+ height : 20px;
}
&-thumb {
- background: linear-gradient(90deg, #d3c1af 15px, #00000000 15px);
- &:horizontal{
- background: linear-gradient(0deg, #d3c1af 15px, #00000000 15px);
- }
- }
- &-corner {
- visibility: hidden;
+ background : linear-gradient(90deg, #D3C1AF 15px, #00000000 15px);
+ &:horizontal { background : linear-gradient(0deg, #D3C1AF 15px, #00000000 15px); }
}
+ &-corner { visibility : hidden; }
}
}
}
diff --git a/client/homebrew/navbar/error-navitem.less b/client/homebrew/navbar/error-navitem.less
index be138dca4..637ddac95 100644
--- a/client/homebrew/navbar/error-navitem.less
+++ b/client/homebrew/navbar/error-navitem.less
@@ -1,78 +1,70 @@
.navItem.error {
- position : relative;
- background-color : @red;
+ position : relative;
+ background-color : @red;
}
-.errorContainer{
- animation-name: glideDown;
- animation-duration: 0.4s;
- position : absolute;
- top : 100%;
- left : 50%;
- z-index : 1000;
- width : 140px;
- padding : 3px;
- color : white;
- background-color : #333;
- border : 3px solid #444;
- border-radius : 5px;
- transform : translate(-50% + 3px, 10px);
- text-align : center;
- font-size : 10px;
- font-weight : 800;
- text-transform : uppercase;
- .lowercase {
- text-transform : none;
+.errorContainer {
+ position : absolute;
+ top : 100%;
+ left : 50%;
+ z-index : 1000;
+ width : 140px;
+ padding : 3px;
+ font-size : 10px;
+ font-weight : 800;
+ color : white;
+ text-align : center;
+ text-transform : uppercase;
+ background-color : #333333;
+ border : 3px solid #444444;
+ border-radius : 5px;
+ transform : translate(-50% + 3px, 10px);
+ animation-name : glideDown;
+ animation-duration : 0.4s;
+ .lowercase { text-transform : none; }
+ a { color : @teal; }
+ &::before {
+ position : absolute;
+ top : -23px;
+ left : 53px;
+ width : 0px;
+ height : 0px;
+ content : '';
+ border-top : 10px solid transparent;
+ border-right : 10px solid transparent;
+ border-bottom : 10px solid #444444;
+ border-left : 10px solid transparent;
+ }
+ &::after {
+ position : absolute;
+ top : -19px;
+ left : 53px;
+ width : 0px;
+ height : 0px;
+ content : '';
+ border-top : 10px solid transparent;
+ border-right : 10px solid transparent;
+ border-bottom : 10px solid #333333;
+ border-left : 10px solid transparent;
+ }
+ .deny {
+ display : inline-block;
+ width : 48%;
+ padding : 5px;
+ margin : 1px;
+ background-color : #333333;
+ border-left : 1px solid #666666;
+ .animate(background-color);
+ &:hover { background-color : red; }
+ }
+ .confirm {
+ display : inline-block;
+ width : 48%;
+ padding : 5px;
+ margin : 1px;
+ color : white;
+ background-color : #333333;
+ .animate(background-color);
+ &:hover { background-color : teal; }
}
- a{
- color : @teal;
- }
- &:before {
- content: "";
- width: 0px;
- height: 0px;
- position: absolute;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- border-top: 10px solid transparent;
- border-bottom: 10px solid #444;
- left: 53px;
- top: -23px;
- }
- &:after {
- content: "";
- width: 0px;
- height: 0px;
- position: absolute;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- border-top: 10px solid transparent;
- border-bottom: 10px solid #333;
- left: 53px;
- top: -19px;
- }
- .deny {
- width : 48%;
- margin : 1px;
- padding : 5px;
- background-color : #333;
- display : inline-block;
- border-left : 1px solid #666;
- .animate(background-color);
- &:hover{
- background-color : red;
- }
- }
- .confirm {
- width : 48%;
- margin : 1px;
- padding : 5px;
- background-color : #333;
- display : inline-block;
- color : white;
- .animate(background-color);
- &:hover{
- background-color : teal;
- }
- }
}
diff --git a/client/homebrew/navbar/navbar.less b/client/homebrew/navbar/navbar.less
index ae11c1e7e..aa233d631 100644
--- a/client/homebrew/navbar/navbar.less
+++ b/client/homebrew/navbar/navbar.less
@@ -24,11 +24,11 @@
}
.homebrew nav {
+ position : relative;
+ z-index : 2;
+ display : flex;
+ justify-content : space-between;
background-color : #333333;
- position : relative;
- z-index : 2;
- display : flex;
- justify-content : space-between;
.navSection {
display : flex;
@@ -82,8 +82,8 @@
font-weight : 800;
line-height : 13px;
color : white;
- text-decoration : none;
text-transform : uppercase;
+ text-decoration : none;
cursor : pointer;
background-color : #333333;
i {
@@ -106,11 +106,11 @@
display : block;
width : 100%;
overflow : hidden;
+ text-overflow : ellipsis;
font-size : 12px;
font-weight : 800;
color : white;
text-align : center;
- text-overflow : ellipsis;
text-transform : initial;
white-space : nowrap;
background-color : transparent;
@@ -170,16 +170,16 @@
h4 {
box-sizing : border-box;
display : block;
- flex-basis : 20%;
flex-grow : 1;
+ flex-basis : 20%;
min-width : 76px;
padding : 5px 0;
color : #BBBBBB;
text-align : center;
}
p {
- flex-basis : 80%;
flex-grow : 1;
+ flex-basis : 80%;
padding : 5px 0;
font-family : 'Open Sans', sans-serif;
font-size : 10px;
@@ -215,10 +215,10 @@
z-index : 10000;
box-sizing : border-box;
display : block;
+ visibility : hidden;
width : 100%;
padding : 13px 5px;
text-align : center;
- visibility : hidden;
background-color : #333333;
}
}
diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx
index ef98e8425..ef309a613 100644
--- a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx
+++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx
@@ -30,11 +30,11 @@ const BrewItem = ({
}
request.delete(`/api/${brew.googleId ?? ''}${brew.editId}`).send().end((err, res)=>{
- if (err) reportError(err); else window.location.reload();
- });
+ if(err) reportError(err); else window.location.reload();
+ });
}, [brew, reportError]);
- const updateFilter = useCallback((type, term)=> updateListFilter(type, term), [updateListFilter]);
+ const updateFilter = useCallback((type, term)=>updateListFilter(type, term), [updateListFilter]);
const renderDeleteBrewLink = ()=>{
if(!brew.editId) return null;
diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less
index a3c17215e..0d45e8537 100644
--- a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less
+++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less
@@ -1,148 +1,129 @@
-.brewItem{
+.brewItem {
position : relative;
+ box-sizing : border-box;
display : inline-block;
- vertical-align : top;
- box-sizing : border-box;
- box-sizing : border-box;
- overflow : hidden;
width : 48%;
min-height : 105px;
- margin-right : 15px;
- margin-bottom : 15px;
padding : 5px 15px 2px 6px;
padding-right : 15px;
- border : 1px solid #c9ad6a;
+ margin-right : 15px;
+ margin-bottom : 15px;
+ overflow : hidden;
+ vertical-align : top;
+ background-color : #CAB2802E;
+ border : 1px solid #C9AD6A;
border-radius : 5px;
+ box-shadow : 0px 4px 5px 0px #333333;
+ break-inside : avoid;
-webkit-column-break-inside : avoid;
page-break-inside : avoid;
- break-inside : avoid;
- box-shadow : 0px 4px 5px 0px #333;
- background-color : #cab2802e;
- .thumbnail {
- position: absolute;
- width: 150px;
- height: 100%;
- top: 0;
- right: 0;
- z-index: -1;
- background-size: contain;
- background-repeat: no-repeat;
- background-position: right top;
- mask-image: linear-gradient(80deg, #0000 20%, #050 40%);
- -webkit-mask-image: linear-gradient(80deg, #0000 20%, #050 40%);
- opacity: 50%;
+ .thumbnail {
+ position : absolute;
+ top : 0;
+ right : 0;
+ z-index : -1;
+ width : 150px;
+ height : 100%;
+ background-repeat : no-repeat;
+ background-position : right top;
+ background-size : contain;
+ opacity : 50%;
+ -webkit-mask-image : linear-gradient(80deg, #00000000 20%, #005500 40%);
+ mask-image : linear-gradient(80deg, #00000000 20%, #005500 40%);
}
.text {
min-height : 54px;
- h4{
+ h4 {
margin-bottom : 5px;
font-size : 2.2em;
}
}
- .info{
- position: initial;
- bottom: 2px;
- font-family : ScalySansRemake;
+ .info {
+ position : initial;
+ bottom : 2px;
+ font-family : "ScalySansRemake";
font-size : 1.2em;
- &>span{
+ & > span {
margin-right : 12px;
line-height : 1.5em;
- a {
- color:inherit;
- }
+ a { color : inherit; }
}
}
.brewTags span {
- background-color: #c8ac6e3b;
- margin: 2px;
- padding: 2px;
- border: 1px solid #c8ac6e;
- border-radius: 4px;
- white-space: nowrap;
- display: inline-block;
- font-weight: bold;
- border-color: currentColor;
- cursor : pointer;
- &:before {
- font-family: 'Font Awesome 5 Free';
- font-size: 12px;
- margin-right: 3px;
+ display : inline-block;
+ padding : 2px;
+ margin : 2px;
+ font-weight : bold;
+ white-space : nowrap;
+ cursor : pointer;
+ background-color : #C8AC6E3B;
+ border : 1px solid #C8AC6E;
+ border-color : currentColor;
+ border-radius : 4px;
+ &::before {
+ margin-right : 3px;
+ font-family : 'Font Awesome 5 Free';
+ font-size : 12px;
}
&.type {
- background-color: #0080003b;
- color: #008000;
- &:before{
- content: '\f0ad';
- }
+ color : #008000;
+ background-color : #0080003B;
+ &::before { content : '\f0ad'; }
}
&.group {
- background-color: #5050503b;
- color: #000000;
- &:before{
- content: '\f500';
- }
+ color : #000000;
+ background-color : #5050503B;
+ &::before { content : '\f500'; }
}
&.meta {
- background-color: #0000803b;
- color: #000080;
- &:before{
- content: '\f05a';
- }
+ color : #000080;
+ background-color : #0000803B;
+ &::before { content : '\f05a'; }
}
&.system {
- background-color: #8000003b;
- color: #800000;
- &:before{
- content: '\f518';
- }
+ color : #800000;
+ background-color : #8000003B;
+ &::before { content : '\f518'; }
}
}
- &:hover{
- .links{
- opacity : 1;
- }
+ &:hover {
+ .links { opacity : 1; }
}
- &:nth-child(2n + 1){
- margin-right : 0px;
- }
- .links{
+ &:nth-child(2n + 1) { margin-right : 0px; }
+ .links {
.animate(opacity);
position : absolute;
top : 0px;
right : 0px;
- height : 100%;
width : 2em;
- opacity : 0;
- background-color : fade(black, 60%);
+ height : 100%;
text-align : center;
- a{
+ background-color : fade(black, 60%);
+ opacity : 0;
+ a {
.animate(opacity);
display : block;
margin : 8px 0px;
- opacity : 0.6;
font-size : 1.3em;
color : white;
text-decoration : unset;
- &:hover{
- opacity : 1;
- }
- i{
- cursor : pointer;
- }
+ opacity : 0.6;
+ &:hover { opacity : 1; }
+ i { cursor : pointer; }
}
}
.googleDriveIcon {
- height : 18px;
+ height : 18px;
padding : 0px;
margin : -5px;
}
.homebreweryIcon {
- mix-blend-mode : darken;
- height : 24px;
position : relative;
top : 5px;
left : -5px;
+ height : 24px;
+ mix-blend-mode : darken;
}
}
diff --git a/client/homebrew/pages/basePages/listPage/listPage.less b/client/homebrew/pages/basePages/listPage/listPage.less
index 0aa4a278d..bf899bc71 100644
--- a/client/homebrew/pages/basePages/listPage/listPage.less
+++ b/client/homebrew/pages/basePages/listPage/listPage.less
@@ -1,5 +1,5 @@
-.noColumns(){
+.noColumns() {
column-count : auto;
column-fill : auto;
column-gap : normal;
@@ -13,177 +13,151 @@
height : auto;
min-height : 279.4mm;
margin : 20px auto;
- contain : unset;
+ contain : unset;
}
-.listPage{
- .content{
+.listPage {
+ .content {
z-index : 1;
- .page{
+ .page {
.noColumns() !important; //Needed to override PHB Theme since this is on a lower @layer
- &::after{
- display : none;
- }
- .noBrews{
+ &::after { display : none; }
+ .noBrews {
margin : 10px 0px;
font-size : 1.3em;
font-style : italic;
}
.brewCollection {
- h1:hover{
- cursor: pointer;
- }
+ h1:hover { cursor : pointer; }
.active::before, .inactive::before {
- font-family: 'Font Awesome 5 Free';
- font-weight: 900;
- font-size: 0.6cm;
- padding-right: 0.5em;
- }
- .active {
- color: var(--HB_Color_HeaderText);
- }
- .active::before {
- content: '\f107';
- }
- .inactive {
- color: #707070;
- }
- .inactive::before {
- content: '\f105';
+ padding-right : 0.5em;
+ font-family : 'Font Awesome 5 Free';
+ font-size : 0.6cm;
+ font-weight : 900;
}
+ .active { color : var(--HB_Color_HeaderText); }
+ .active::before { content : '\f107'; }
+ .inactive { color : #707070; }
+ .inactive::before { content : '\f105'; }
}
}
}
.sort-container {
- font-family : 'Open Sans', sans-serif;
- position : sticky;
- top : 0;
- left : 0;
- width : 100%;
- height : 30px;
- background-color : #555;
- border-top : 1px solid #666;
- border-bottom : 1px solid #666;
- color : white;
- text-align : center;
- z-index : 1;
- display : flex;
- justify-content : center;
- align-items : baseline;
- column-gap : 15px;
- row-gap : 5px;
- flex-wrap : wrap;
- h6{
- text-transform : uppercase;
+ position : sticky;
+ top : 0;
+ left : 0;
+ z-index : 1;
+ display : flex;
+ flex-wrap : wrap;
+ row-gap : 5px;
+ column-gap : 15px;
+ align-items : baseline;
+ justify-content : center;
+ width : 100%;
+ height : 30px;
+ font-family : 'Open Sans', sans-serif;
+ color : white;
+ text-align : center;
+ background-color : #555555;
+ border-top : 1px solid #666666;
+ border-bottom : 1px solid #666666;
+ h6 {
font-family : 'Open Sans', sans-serif;
font-size : 11px;
font-weight : bold;
+ text-transform : uppercase;
}
.sort-option {
- display: flex;
- align-items: center;
- padding: 0 8px;
- color: #ccc;
- height: 100%;
+ display : flex;
+ align-items : center;
+ height : 100%;
+ padding : 0 8px;
+ color : #CCCCCC;
- &:hover{
- background-color : #444;
- }
+ &:hover { background-color : #444444; }
&.active {
- font-weight: bold;
- color: #ddd;
- background-color: #333;
+ font-weight : bold;
+ color : #DDDDDD;
+ background-color : #333333;
- button {
- color: white;
- font-weight: 800;
- height: 100%;
- & + .sortDir {
- padding-left: 5px;
+ button {
+ height : 100%;
+ font-weight : 800;
+ color : white;
+ & + .sortDir { padding-left : 5px; }
}
}
- }
}
.filter-option {
- margin-left: 20px;
- background-color : transparent !important;
+ margin-left : 20px;
font-size : 11px;
- i{
- padding-right : 5px;
- }
+ background-color : transparent !important;
+ i { padding-right : 5px; }
+ }
+ button {
+ padding : 0;
+ font-family : 'Open Sans', sans-serif;
+ font-size : 11px;
+ font-weight : normal;
+ color : #CCCCCC;
+ text-transform : uppercase;
+ background-color : transparent;
}
- button{
- background-color : transparent;
- font-family : 'Open Sans', sans-serif;
- text-transform : uppercase;
- font-weight : normal;
- font-size : 11px;
- color : #ccc;
- padding : 0;
- }
}
.tags-container {
- height : 30px;
- background-color : #555;
- border-top : 1px solid #666;
- border-bottom : 1px solid #666;
- color : white;
display : flex;
- justify-content : center;
- align-items : center;
- column-gap : 15px;
- row-gap : 5px;
flex-wrap : wrap;
+ row-gap : 5px;
+ column-gap : 15px;
+ align-items : center;
+ justify-content : center;
+ height : 30px;
+ color : white;
+ background-color : #555555;
+ border-top : 1px solid #666666;
+ border-bottom : 1px solid #666666;
span {
+ padding : 3px;
font-family : 'Open Sans', sans-serif;
font-size : 11px;
font-weight : bold;
+ color : #DFDFDF;
+ cursor : pointer;
border : 1px solid;
border-radius : 3px;
- padding : 3px;
- cursor : pointer;
- color: #dfdfdf;
- &:before {
- font-family: 'Font Awesome 5 Free';
- font-size: 12px;
- margin-right: 3px;
+ &::before {
+ margin-right : 3px;
+ font-family : 'Font Awesome 5 Free';
+ font-size : 12px;
}
- &:after {
- content: '\f00d';
- font-family: 'Font Awesome 5 Free';
- font-size: 12px;
- margin-left: 3px;
+ &::after {
+ margin-left : 3px;
+ font-family : 'Font Awesome 5 Free';
+ font-size : 12px;
+ content : '\f00d';
}
&.type {
- background-color: #008000;
- border-color: #00a000;
- &:before{
- content: '\f0ad';
- }
+ background-color : #008000;
+ border-color : #00A000;
+ &::before { content : '\f0ad'; }
}
&.group {
- background-color: #505050;
- border-color: #000000;
- &:before{
- content: '\f500';
- }
+ background-color : #505050;
+ border-color : #000000;
+ &::before { content : '\f500'; }
}
&.meta {
- background-color: #000080;
- border-color: #0000a0;
- &:before{
- content: '\f05a';
- }
+ background-color : #000080;
+ border-color : #0000A0;
+ &::before { content : '\f05a'; }
}
&.system {
- background-color: #800000;
- border-color: #a00000;
- &:before{
- content: '\f518';
- }
+ background-color : #800000;
+ border-color : #A00000;
+ &::before { content : '\f518'; }
}
}
}
diff --git a/client/homebrew/pages/basePages/uiPage/uiPage.less b/client/homebrew/pages/basePages/uiPage/uiPage.less
index 49cb8311d..27f079e20 100644
--- a/client/homebrew/pages/basePages/uiPage/uiPage.less
+++ b/client/homebrew/pages/basePages/uiPage/uiPage.less
@@ -1,7 +1,7 @@
.homebrew {
.uiPage.sitePage {
.content {
- width : ~"min(90vw, 1000px)";
+ width : ~'min(90vw, 1000px)';
padding : 2% 4%;
margin-top : 25px;
margin-right : auto;
@@ -17,19 +17,19 @@
border : 2px solid black;
border-radius : 5px;
button {
+ width : 125px;
+ margin-right : 5px;
+ color : black;
background-color : transparent;
border : 1px solid black;
border-radius : 5px;
- width : 125px;
- color : black;
- margin-right : 5px;
&.active {
- background-color: #0007;
- color: white;
- &:before {
- content: '\f00c';
- font-family: 'FONT AWESOME 5 FREE';
- margin-right: 5px;
+ color : white;
+ background-color : #00000077;
+ &::before {
+ margin-right : 5px;
+ font-family : 'FONT AWESOME 5 FREE';
+ content : '\f00c';
}
}
}
@@ -59,6 +59,11 @@
padding-left : 1.25em;
list-style : square;
}
+ .blank {
+ height : 1em;
+ margin-top : 0;
+ & + * { margin-top : 0; }
+ }
}
}
}
\ No newline at end of file
diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx
index dc2520373..f2b1e809f 100644
--- a/client/homebrew/pages/editPage/editPage.jsx
+++ b/client/homebrew/pages/editPage/editPage.jsx
@@ -150,6 +150,18 @@ const EditPage = createClass({
}), ()=>{if(this.state.autoSave) this.trySave();});
},
+ handleSnipChange : function(snippet){
+ //If there are errors, run the validator on every change to give quick feedback
+ let htmlErrors = this.state.htmlErrors;
+ if(htmlErrors.length) htmlErrors = Markdown.validate(snippet);
+
+ this.setState((prevState)=>({
+ brew : { ...prevState.brew, snippets: snippet },
+ isPending : true,
+ htmlErrors : htmlErrors,
+ }), ()=>{if(this.state.autoSave) this.trySave();});
+ },
+
handleStyleChange : function(style){
this.setState((prevState)=>({
brew : { ...prevState.brew, style: style }
@@ -443,7 +455,7 @@ const EditPage = createClass({
{this.renderNavbar()}
- {this.props.brew.lock &&
}
+ {this.props.brew.lock &&
}
{},
- message : '',
+ shareId : 0,
+ disableLock : ()=>{},
+ lock : {},
+ message : 'Unable to retrieve Lock Message',
+ reviewRequested : false,
...props
};
- const removeLock = ()=>{
- alert(`Not yet implemented - ID ${props.shareId}`);
+ const [reviewState, setReviewState] = React.useState(props.reviewRequested);
+
+ const removeLock = async ()=>{
+ await request.put(`/api/lock/review/request/${props.shareId}`)
+ .then(()=>{
+ setReviewState(true);
+ });
+ };
+
+ const renderReviewButton = function(){
+ if(reviewState){ return REVIEW REQUESTED ; };
+ return REQUEST LOCK REMOVAL ;
};
return
@@ -19,11 +32,11 @@ function LockNotification(props) {
This brew been locked by the Administrators. It will not be accessible by any method other than the Editor until the lock is removed.
LOCK REASON
- {props.message || 'Unable to retrieve Lock Message'}
+ {props.message}
Once you have resolved this issue, click REQUEST LOCK REMOVAL to notify the Administrators for review.
Click CONTINUE TO EDITOR to temporarily hide this notification; it will reappear the next time the page is reloaded.
- REQUEST LOCK REMOVAL
+ {renderReviewButton()}
;
};
diff --git a/client/homebrew/pages/editPage/lockNotification/lockNotification.less b/client/homebrew/pages/editPage/lockNotification/lockNotification.less
index 54f1a9569..930b070c4 100644
--- a/client/homebrew/pages/editPage/lockNotification/lockNotification.less
+++ b/client/homebrew/pages/editPage/lockNotification/lockNotification.less
@@ -11,10 +11,12 @@
&::backdrop { background-color : #000000AA; }
button {
+ padding : 2px 15px;
margin : 10px;
color : white;
background-color : #333333;
+ &.inactive,
&:hover { background-color : #777777; }
}
diff --git a/client/homebrew/pages/errorPage/errors/errorIndex.js b/client/homebrew/pages/errorPage/errors/errorIndex.js
index c2c49f958..b13b19eb1 100644
--- a/client/homebrew/pages/errorPage/errors/errorIndex.js
+++ b/client/homebrew/pages/errorPage/errors/errorIndex.js
@@ -167,7 +167,7 @@ const errorIndex = (props)=>{
**Requested access:** ${props.brew.accessType}
**Brew ID:** ${props.brew.brewId}`,
-
+
// Theme Not Valid
'10' : dedent`
## The selected theme is not tagged as a theme.
@@ -194,13 +194,47 @@ const errorIndex = (props)=>{
**Brew ID:** ${props.brew.brewId}
- **Brew Title:** ${escape(props.brew.brewTitle)}`,
+ **Brew Title:** ${escape(props.brew.brewTitle)}
+
+ **Brew Authors:** ${props.brew.authors?.map((author)=>{return `[${author}](/user/${author})`;}).join(', ') || 'Unable to list authors'}`,
// ####### Admin page error #######
'52' : dedent`
## Access Denied
You need to provide correct administrator credentials to access this page.`,
+ // ####### Lock Errors
+
+ '60' : dedent`Lock Error: General`,
+
+ '61' : dedent`Lock Get Error: Unable to get lock count`,
+
+ '62' : dedent`Lock Set Error: Cannot lock`,
+
+ '63' : dedent`Lock Set Error: Brew not found`,
+
+ '64' : dedent`Lock Set Error: Already locked`,
+
+ '65' : dedent`Lock Remove Error: Cannot unlock`,
+
+ '66' : dedent`Lock Remove Error: Brew not found`,
+
+ '67' : dedent`Lock Remove Error: Not locked`,
+
+ '68' : dedent`Lock Get Review Error: Cannot get review requests`,
+
+ '69' : dedent`Lock Set Review Error: Cannot set review request`,
+
+ '70' : dedent`Lock Set Review Error: Brew not found`,
+
+ '71' : dedent`Lock Set Review Error: Review already requested`,
+
+ '72' : dedent`Lock Remove Review Error: Cannot clear review request`,
+
+ '73' : dedent`Lock Remove Review Error: Brew not found`,
+
+ // ####### Other Errors
+
'90' : dedent` An unexpected error occurred while looking for these brews.
Try again in a few minutes.`,
diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx
index 00d0c801d..d03e30c91 100644
--- a/client/homebrew/pages/homePage/homePage.jsx
+++ b/client/homebrew/pages/homePage/homePage.jsx
@@ -100,32 +100,32 @@ const HomePage = createClass({
return
{this.renderNavbar()}
-
-
-
-
-
+
+
+
+
+
Save current
diff --git a/client/homebrew/pages/homePage/homePage.less b/client/homebrew/pages/homePage/homePage.less
index a7523bd3c..4cf9ff4fe 100644
--- a/client/homebrew/pages/homePage/homePage.less
+++ b/client/homebrew/pages/homePage/homePage.less
@@ -1,50 +1,40 @@
-.homePage{
+.homePage {
position : relative;
- a.floatingNewButton{
+ a.floatingNewButton {
.animate(background-color);
position : absolute;
- display : block;
right : 70px;
bottom : 50px;
- z-index : 100;
z-index : 5001;
+ display : block;
padding : 1em;
- background-color : @orange;
font-size : 1.5em;
color : white;
text-decoration : none;
+ background-color : @orange;
box-shadow : 3px 3px 15px black;
- &:hover{
- background-color : darken(@orange, 20%);
- }
+ &:hover { background-color : darken(@orange, 20%); }
}
- .floatingSaveButton{
+ .floatingSaveButton {
.animateAll();
position : absolute;
- display : block;
right : 200px;
bottom : 70px;
- z-index : 100;
z-index : 5000;
+ display : block;
padding : 0.8em;
- cursor : pointer;
- background-color : @blue;
font-size : 0.8em;
color : white;
text-decoration : none;
+ cursor : pointer;
+ background-color : @blue;
box-shadow : 3px 3px 15px black;
- &:hover{
- background-color : darken(@blue, 20%);
- }
- &.show{
- right : 350px;
- }
+ &:hover { background-color : darken(@blue, 20%); }
+ &.show { right : 350px; }
}
- .navItem.save{
- background-color: @orange;
- &:hover{
- background-color: @green;
- }
+ .navItem.save {
+ background-color : @orange;
+ &:hover { background-color : @green; }
}
}
diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx
index 1d5887b8a..3e4e5ce41 100644
--- a/client/homebrew/pages/newPage/newPage.jsx
+++ b/client/homebrew/pages/newPage/newPage.jsx
@@ -141,6 +141,18 @@ const NewPage = createClass({
localStorage.setItem(STYLEKEY, style);
},
+ handleSnipChange : function(snippet){
+ //If there are errors, run the validator on every change to give quick feedback
+ let htmlErrors = this.state.htmlErrors;
+ if(htmlErrors.length) htmlErrors = Markdown.validate(snippet);
+
+ this.setState((prevState)=>({
+ brew : { ...prevState.brew, snippets: snippet },
+ isPending : true,
+ htmlErrors : htmlErrors,
+ }), ()=>{if(this.state.autoSave) this.trySave();});
+ },
+
handleMetaChange : function(metadata, field=undefined){
if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed
fetchThemeBundle(this, metadata.renderer, metadata.theme);
@@ -223,39 +235,39 @@ const NewPage = createClass({
render : function(){
return
{this.renderNavbar()}
-
;
}
diff --git a/client/homebrew/pages/newPage/newPage.less b/client/homebrew/pages/newPage/newPage.less
index f83827ffb..ebc44d543 100644
--- a/client/homebrew/pages/newPage/newPage.less
+++ b/client/homebrew/pages/newPage/newPage.less
@@ -1,8 +1,6 @@
-.newPage{
- .navItem.save{
- background-color: @orange;
- &:hover{
- background-color: @green;
- }
+.newPage {
+ .navItem.save {
+ background-color : @orange;
+ &:hover { background-color : @green; }
}
}
diff --git a/client/homebrew/pages/sharePage/sharePage.less b/client/homebrew/pages/sharePage/sharePage.less
index 754108506..b76dc50f9 100644
--- a/client/homebrew/pages/sharePage/sharePage.less
+++ b/client/homebrew/pages/sharePage/sharePage.less
@@ -1,9 +1,7 @@
-.sharePage{
+.sharePage {
nav .navSection.titleSection {
- flex-grow: 1;
- justify-content: center;
- }
- .content{
- overflow-y : hidden;
+ flex-grow : 1;
+ justify-content : center;
}
+ .content { overflow-y : hidden; }
}
diff --git a/client/homebrew/pages/vaultPage/vaultPage.jsx b/client/homebrew/pages/vaultPage/vaultPage.jsx
index 21a8e8363..f979aa4f7 100644
--- a/client/homebrew/pages/vaultPage/vaultPage.jsx
+++ b/client/homebrew/pages/vaultPage/vaultPage.jsx
@@ -99,14 +99,14 @@ const VaultPage = (props)=>{
setSearching(true);
setError(null);
- const title = titleRef.current.value || '';
- const author = authorRef.current.value || '';
- const count = countRef.current.value || 10;
- const v3 = v3Ref.current.checked != false;
- const legacy = legacyRef.current.checked != false;
+ const title = titleRef.current.value || '';
+ const author = authorRef.current.value || '';
+ const count = countRef.current.value || 10;
+ const v3 = v3Ref.current.checked != false;
+ const legacy = legacyRef.current.checked != false;
const sortOption = sort || 'title';
- const dirOption = dir || 'asc';
- const pageProp = page || 1;
+ const dirOption = dir || 'asc';
+ const pageProp = page || 1;
setSort(sortOption);
setdir(dirOption);
@@ -247,7 +247,7 @@ const VaultPage = (props)=>{
Some common words like "a", "after", "through", "itself", "here", etc.,
- are ignored in searches. The full list can be found
+ are ignored in searches. The full list can be found
here
@@ -286,9 +286,9 @@ const VaultPage = (props)=>{
};
const renderPaginationControls = ()=>{
- if(!totalBrews) return null;
+ if(!totalBrews || totalBrews < 10) return null;
- const countInt = parseInt(props.query.count || 20);
+ const countInt = parseInt(brewCollection.length || 20);
const totalPages = Math.ceil(totalBrews / countInt);
let startPage, endPage;
@@ -355,7 +355,7 @@ const VaultPage = (props)=>{
};
const renderFoundBrews = ()=>{
- if(searching) {
+ if(searching && !brewCollection) {
return (
Searching
@@ -395,6 +395,7 @@ const VaultPage = (props)=>{
{`Brews found: `}
{totalBrews}
+ {brewCollection.length > 10 && renderPaginationControls()}
{brewCollection.map((brew, index)=>{
return (
{
{renderNavItems()}
-
-
- {renderForm()}
-
- {renderSortBar()}
- {renderFoundBrews()}
-
-
+
+
+ {renderForm()}
+
+ {renderSortBar()}
+ {renderFoundBrews()}
+
+
);
diff --git a/client/homebrew/pages/vaultPage/vaultPage.less b/client/homebrew/pages/vaultPage/vaultPage.less
index a69bcb33b..8a5f3a714 100644
--- a/client/homebrew/pages/vaultPage/vaultPage.less
+++ b/client/homebrew/pages/vaultPage/vaultPage.less
@@ -5,7 +5,7 @@
*:not(input) { user-select : none; }
- .content .dataGroup {
+ :where(.content .dataGroup) {
width : 100%;
height : 100%;
background : white;
@@ -169,9 +169,10 @@
width : 100%;
height : 100%;
max-height : 100%;
- padding : 50px 50px 70px 50px;
+ padding : 70px 50px;
overflow-y : scroll;
background-color : #2C3E50;
+ container-type : inline-size;
h3 { font-size : 25px; }
@@ -236,6 +237,7 @@
margin-right : 40px;
color : black;
isolation : isolate;
+ transition : width 0.5s;
&::after {
position : absolute;
@@ -269,8 +271,8 @@
.links { z-index : 2; }
hr {
- margin : 0px;
visibility : hidden;
+ margin : 0px;
}
.thumbnail { z-index : -1; }
@@ -278,30 +280,37 @@
.paginationControls {
position : absolute;
+ top : 35px;
left : 50%;
display : grid;
grid-template-areas : 'previousPage currentPage nextPage';
grid-template-columns : 50px 1fr 50px;
+ gap : 20px;
place-items : center;
width : auto;
+ font-size : 15px;
translate : -50%;
+ &:last-child { top : unset; }
+
.pages {
display : flex;
grid-area : currentPage;
+ gap : 1em;
justify-content : space-evenly;
width : 100%;
height : 100%;
- padding : 5px 8px;
text-align : center;
.pageNumber {
- margin-inline : 1vw;
+ place-content : center;
+ width : fit-content;
+ min-width : 2em;
font-family : 'Open Sans';
font-weight : 900;
color : white;
- text-underline-position : under;
text-wrap : nowrap;
+ text-underline-position : under;
cursor : pointer;
&.currentPage {
@@ -329,7 +338,6 @@
}
}
}
-
}
@keyframes trailingDots {
@@ -344,8 +352,7 @@
100% { content : ' ...'; }
}
-// media query for when the page is smaller than 1079 px in width
-@media screen and (max-width : 1079px) {
+@container (width < 670px) {
.vaultPage {
.dataGroup.form .brewLookup { padding : 1px 20px 20px 10px; }
diff --git a/client/icons/customIcons.less b/client/icons/customIcons.less
index 1c8d1bd47..a2caffc57 100644
--- a/client/icons/customIcons.less
+++ b/client/icons/customIcons.less
@@ -1,84 +1,34 @@
.fac {
display : inline-block;
- background-color : currentColor;
- mask-size : contain;
- mask-repeat : no-repeat;
- mask-position : center;
width : 1em;
aspect-ratio : 1;
+ background-color : currentColor;
+ mask-repeat : no-repeat;
+ mask-position : center;
+ mask-size : contain;
}
-.position-top-left {
- mask-image: url('../icons/position-top-left.svg');
-}
-.position-top-right {
- mask-image: url('../icons/position-top-right.svg');
-}
-.position-bottom-left {
- mask-image: url('../icons/position-bottom-left.svg');
-}
-.position-bottom-right {
- mask-image: url('../icons/position-bottom-right.svg');
-}
-.position-top {
- mask-image: url('../icons/position-top.svg');
-}
-.position-right {
- mask-image: url('../icons/position-right.svg');
-}
-.position-bottom {
- mask-image: url('../icons/position-bottom.svg');
-}
-.position-left {
- mask-image: url('../icons/position-left.svg');
-}
-.mask-edge {
- mask-image: url('../icons/mask-edge.svg');
-}
-.mask-corner {
- mask-image: url('../icons/mask-corner.svg');
-}
-.mask-center {
- mask-image: url('../icons/mask-center.svg');
-}
-.book-front-cover {
- mask-image: url('../icons/book-front-cover.svg');
-}
-.book-back-cover {
- mask-image: url('../icons/book-back-cover.svg');
-}
-.book-inside-cover {
- mask-image: url('../icons/book-inside-cover.svg');
-}
-.book-part-cover {
- mask-image: url('../icons/book-part-cover.svg');
-}
-.image-wrap-left {
- mask-image: url('../icons/image-wrap-left.svg');
-}
-.image-wrap-right {
- mask-image: url('../icons/image-wrap-right.svg');
-}
-.davek {
- mask-image: url('../icons/Davek.svg');
-}
-.rellanic {
- mask-image: url('../icons/Rellanic.svg');
-}
-.iokharic {
- mask-image: url('../icons/Iokharic.svg');
-}
-.zoom-to-fit {
- mask-image: url('../icons/zoom-to-fit.svg');
-}
-.fit-width {
- mask-image: url('../icons/fit-width.svg');
-}
-.single-spread {
- mask-image: url('../icons/single-spread.svg');
-}
-.facing-spread {
- mask-image: url('../icons/facing-spread.svg');
-}
-.flow-spread {
- mask-image: url('../icons/flow-spread.svg');
-}
+.position-top-left { mask-image : url('../icons/position-top-left.svg'); }
+.position-top-right { mask-image : url('../icons/position-top-right.svg'); }
+.position-bottom-left { mask-image : url('../icons/position-bottom-left.svg'); }
+.position-bottom-right { mask-image : url('../icons/position-bottom-right.svg'); }
+.position-top { mask-image : url('../icons/position-top.svg'); }
+.position-right { mask-image : url('../icons/position-right.svg'); }
+.position-bottom { mask-image : url('../icons/position-bottom.svg'); }
+.position-left { mask-image : url('../icons/position-left.svg'); }
+.mask-edge { mask-image : url('../icons/mask-edge.svg'); }
+.mask-corner { mask-image : url('../icons/mask-corner.svg'); }
+.mask-center { mask-image : url('../icons/mask-center.svg'); }
+.book-front-cover { mask-image : url('../icons/book-front-cover.svg'); }
+.book-back-cover { mask-image : url('../icons/book-back-cover.svg'); }
+.book-inside-cover { mask-image : url('../icons/book-inside-cover.svg'); }
+.book-part-cover { mask-image : url('../icons/book-part-cover.svg'); }
+.image-wrap-left { mask-image : url('../icons/image-wrap-left.svg'); }
+.image-wrap-right { mask-image : url('../icons/image-wrap-right.svg'); }
+.davek { mask-image : url('../icons/Davek.svg'); }
+.rellanic { mask-image : url('../icons/Rellanic.svg'); }
+.iokharic { mask-image : url('../icons/Iokharic.svg'); }
+.zoom-to-fit { mask-image : url('../icons/zoom-to-fit.svg'); }
+.fit-width { mask-image : url('../icons/fit-width.svg'); }
+.single-spread { mask-image : url('../icons/single-spread.svg'); }
+.facing-spread { mask-image : url('../icons/facing-spread.svg'); }
+.flow-spread { mask-image : url('../icons/flow-spread.svg'); }
diff --git a/package-lock.json b/package-lock.json
index 7ac2585a6..82c599f7b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,31 +1,30 @@
{
"name": "homebrewery",
- "version": "3.17.0",
+ "version": "3.18.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "homebrewery",
- "version": "3.17.0",
+ "version": "3.18.1",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
- "@babel/core": "^7.26.9",
- "@babel/plugin-transform-runtime": "^7.26.9",
+ "@babel/core": "^7.26.10",
+ "@babel/plugin-transform-runtime": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.26.3",
- "@googleapis/drive": "^8.16.0",
- "body-parser": "^1.20.2",
+ "@googleapis/drive": "^11.0.0",
+ "body-parser": "^2.2.0",
"classnames": "^2.5.1",
"codemirror": "^5.65.6",
"cookie-parser": "^1.4.7",
- "core-js": "^3.40.0",
+ "core-js": "^3.41.0",
"cors": "^2.8.5",
"create-react-class": "^15.7.0",
"dedent-tabs": "^0.10.3",
- "dompurify": "^3.2.4",
"expr-eval": "^2.0.2",
- "express": "^4.21.2",
+ "express": "^5.1.0",
"express-async-handler": "^1.2.0",
"express-static-gzip": "2.2.0",
"fs-extra": "11.3.0",
@@ -34,76 +33,48 @@
"jwt-simple": "^0.5.6",
"less": "^3.13.1",
"lodash": "^4.17.21",
- "marked": "13.0.3",
- "marked-definition-lists": "^1.0.1",
+ "marked": "15.0.8",
+ "marked-alignment-paragraphs": "^1.0.0",
"marked-emoji": "^2.0.0",
- "marked-extended-tables": "^2.0.0",
+ "marked-extended-tables": "^2.0.1",
"marked-gfm-heading-id": "^4.0.1",
+ "marked-nonbreaking-spaces": "^1.0.1",
"marked-smartypants-lite": "^1.0.3",
"marked-subsuper-text": "^1.0.3",
"markedLegacy": "npm:marked@^0.3.19",
"moment": "^2.30.1",
- "mongoose": "^8.11.0",
- "nanoid": "5.1.2",
- "nconf": "^0.12.1",
+ "mongoose": "^8.13.2",
+ "nanoid": "5.1.5",
+ "nconf": "^0.13.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-frame-component": "^4.1.3",
- "react-router": "^7.2.0",
+ "react-router": "^7.5.0",
+ "romans": "^3.0.0",
"sanitize-filename": "1.6.3",
- "superagent": "^10.1.1",
- "vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
+ "superagent": "^10.2.0",
+ "vitreum": "git+https://git@github.com/calculuschild/vitreum.git",
+ "written-number": "^0.11.1"
},
"devDependencies": {
"@stylistic/stylelint-plugin": "^3.1.2",
"babel-plugin-transform-import-meta": "^2.3.2",
- "eslint": "^9.21.0",
+ "eslint": "^9.24.0",
"eslint-plugin-jest": "^28.11.0",
- "eslint-plugin-react": "^7.37.4",
+ "eslint-plugin-react": "^7.37.5",
"globals": "^16.0.0",
"jest": "^29.7.0",
"jest-expect-message": "^1.1.3",
"jsdom-global": "^3.0.2",
"postcss-less": "^6.0.0",
- "stylelint": "^16.14.1",
+ "stylelint": "^16.18.0",
"stylelint-config-recess-order": "^6.0.0",
- "stylelint-config-recommended": "^15.0.0",
- "supertest": "^7.0.0"
+ "stylelint-config-recommended": "^16.0.0",
+ "supertest": "^7.1.0"
},
"engines": {
"node": "^20.18.x",
- "npm": "^10.2.x"
- }
- },
- "../marked-definition-lists": {
- "version": "1.0.0",
- "extraneous": true,
- "license": "MIT",
- "devDependencies": {
- "@babel/core": "^7.26.0",
- "@babel/preset-env": "^7.26.0",
- "@markedjs/testutils": "^15.0.0-0",
- "@rollup/plugin-commonjs": "^28.0.2",
- "@rollup/plugin-node-resolve": "^16.0.0",
- "@semantic-release/changelog": "^6.0.3",
- "@semantic-release/commit-analyzer": "^13.0.0",
- "@semantic-release/git": "^10.0.1",
- "@semantic-release/github": "^11.0.1",
- "@semantic-release/npm": "^12.0.1",
- "@semantic-release/release-notes-generator": "^14.0.2",
- "babel-jest": "^29.5.0",
- "eslint": "^8.57.1",
- "eslint-config-standard": "^17.1.0",
- "eslint-plugin-import": "^2.31.0",
- "eslint-plugin-node": "^11.1.0",
- "eslint-plugin-promise": "^6.6.0",
- "jest-cli": "^29.7.0",
- "marked": "^15.0.4",
- "rollup": "^4.29.2",
- "semantic-release": "^24.2.0"
- },
- "peerDependencies": {
- "marked": ">=3 <16"
+ "npm": "^10.8.x"
}
},
"node_modules/@ampproject/remapping": {
@@ -143,21 +114,21 @@
}
},
"node_modules/@babel/core": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz",
- "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
+ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.26.9",
+ "@babel/generator": "^7.26.10",
"@babel/helper-compilation-targets": "^7.26.5",
"@babel/helper-module-transforms": "^7.26.0",
- "@babel/helpers": "^7.26.9",
- "@babel/parser": "^7.26.9",
+ "@babel/helpers": "^7.26.10",
+ "@babel/parser": "^7.26.10",
"@babel/template": "^7.26.9",
- "@babel/traverse": "^7.26.9",
- "@babel/types": "^7.26.9",
+ "@babel/traverse": "^7.26.10",
+ "@babel/types": "^7.26.10",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -173,13 +144,13 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz",
- "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz",
+ "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==",
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.26.9",
- "@babel/types": "^7.26.9",
+ "@babel/parser": "^7.26.10",
+ "@babel/types": "^7.26.10",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
@@ -409,25 +380,25 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz",
- "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz",
+ "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.26.9",
- "@babel/types": "^7.26.9"
+ "@babel/template": "^7.27.0",
+ "@babel/types": "^7.27.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz",
- "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
+ "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.26.9"
+ "@babel/types": "^7.27.0"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -579,7 +550,6 @@
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
"integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
- "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -1439,15 +1409,15 @@
}
},
"node_modules/@babel/plugin-transform-runtime": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.9.tgz",
- "integrity": "sha512-Jf+8y9wXQbbxvVYTM8gO5oEF2POdNji0NMltEkG7FtmzD9PVz7/lxpqSdTvwsjTMU5HIHuDVNf2SOxLkWi+wPQ==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.10.tgz",
+ "integrity": "sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==",
"license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.25.9",
"@babel/helper-plugin-utils": "^7.26.5",
"babel-plugin-polyfill-corejs2": "^0.4.10",
- "babel-plugin-polyfill-corejs3": "^0.10.6",
+ "babel-plugin-polyfill-corejs3": "^0.11.0",
"babel-plugin-polyfill-regenerator": "^0.6.1",
"semver": "^6.3.1"
},
@@ -1673,19 +1643,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
- "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.3",
- "core-js-compat": "^3.40.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
"node_modules/@babel/preset-modules": {
"version": "0.1.6-no-external-plugins",
"resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
@@ -1721,9 +1678,10 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz",
- "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
+ "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
+ "license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -1732,30 +1690,30 @@
}
},
"node_modules/@babel/template": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
- "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
+ "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.26.2",
- "@babel/parser": "^7.26.9",
- "@babel/types": "^7.26.9"
+ "@babel/parser": "^7.27.0",
+ "@babel/types": "^7.27.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz",
- "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.10.tgz",
+ "integrity": "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.26.9",
- "@babel/parser": "^7.26.9",
+ "@babel/generator": "^7.26.10",
+ "@babel/parser": "^7.26.10",
"@babel/template": "^7.26.9",
- "@babel/types": "^7.26.9",
+ "@babel/types": "^7.26.10",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -1773,9 +1731,9 @@
}
},
"node_modules/@babel/types": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
- "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
+ "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
@@ -1895,9 +1853,9 @@
}
},
"node_modules/@eslint/config-array": {
- "version": "0.19.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
- "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
+ "version": "0.20.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz",
+ "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -1909,6 +1867,16 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz",
+ "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
"node_modules/@eslint/core": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
@@ -1923,9 +1891,9 @@
}
},
"node_modules/@eslint/eslintrc": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz",
- "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1960,9 +1928,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "9.21.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz",
- "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==",
+ "version": "9.24.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz",
+ "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1980,23 +1948,36 @@
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.2.7",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz",
- "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==",
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz",
+ "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@eslint/core": "^0.12.0",
+ "@eslint/core": "^0.13.0",
"levn": "^0.4.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
+ "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz",
+ "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
"node_modules/@googleapis/drive": {
- "version": "8.16.0",
- "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-8.16.0.tgz",
- "integrity": "sha512-Xi2mMrUTQ+gsfyouRGd0pfnL+jjg4n4sjKsJruM1y4DknuRfdSBTk5E//WrL0YJ/CqpcBgyd7L8DvaPRtxZD3Q==",
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-11.0.0.tgz",
+ "integrity": "sha512-vhkl6/MZ8k5h5XOyenWOD4ys+SNdb8wKYvzU6OBGFx/TzJyHRm4JwgvE8uVDFU6efzNRS0mOiNRfY6nrmHOTtg==",
"license": "Apache-2.0",
"dependencies": {
"googleapis-common": "^7.0.0"
@@ -2726,10 +2707,11 @@
}
},
"node_modules/@keyv/serialize": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.2.tgz",
- "integrity": "sha512-+E/LyaAeuABniD/RvUezWVXKpeuvwLEA9//nE9952zBaOdBd2mQ3pPoM8cUe2X6IcMByfuSLzmYqnYshG60+HQ==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz",
+ "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"buffer": "^6.0.3"
}
@@ -2753,15 +2735,16 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/@mongodb-js/saslprep": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.2.0.tgz",
- "integrity": "sha512-+ywrb0AqkfaYuhHs6LxKWgqbh3I72EpEgESCw37o+9qPx9WTCkgDm2B+eMrwehGtHBWHFU4GXvnSCNiFhhausg==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.2.2.tgz",
+ "integrity": "sha512-EB0O3SCSNRUFk66iRCpI+cXzIjdswfCs7F6nOC3RAGJ7xr5YhaicvsRwJ9eyzYvYRlCSDUO/c7g4yNulxKC1WA==",
"license": "MIT",
"dependencies": {
"sparse-bitfield": "^3.0.3"
@@ -2973,12 +2956,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/trusted-types": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
- "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
- "optional": true
- },
"node_modules/@types/webidl-conversions": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
@@ -3153,22 +3130,43 @@
}
},
"node_modules/accepts": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
- "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
"license": "MIT",
"dependencies": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/accepts/node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/accepts/node_modules/mime-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/acorn": {
- "version": "8.14.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
- "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "version": "8.14.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
+ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"dev": true,
"license": "MIT",
"bin": {
@@ -3278,6 +3276,7 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
@@ -3339,6 +3338,7 @@
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
"integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"is-array-buffer": "^3.0.5"
@@ -3350,12 +3350,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
- "license": "MIT"
- },
"node_modules/array-includes": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
@@ -3441,6 +3435,7 @@
"resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
"integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
@@ -3476,6 +3471,7 @@
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
"integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"array-buffer-byte-length": "^1.0.1",
"call-bind": "^1.0.8",
@@ -3539,6 +3535,7 @@
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -3593,6 +3590,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"
},
@@ -3730,12 +3728,13 @@
}
},
"node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.10.6",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
- "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
+ "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
+ "license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.2",
- "core-js-compat": "^3.38.0"
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
+ "core-js-compat": "^3.40.0"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -3758,6 +3757,7 @@
"resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.3.2.tgz",
"integrity": "sha512-902o4GiQqI1GqAXfD5rEoz0PJamUfJ3VllpdWaNsFTwdaNjFSFHawvBO+cp5K2j+g2h3bZ4lnM1Xb6yFYGihtA==",
"dev": true,
+ "license": "BSD",
"dependencies": {
"@babel/template": "^7.25.9",
"tslib": "^2.8.1"
@@ -3904,6 +3904,16 @@
"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.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
@@ -3911,43 +3921,25 @@
"license": "MIT"
},
"node_modules/body-parser": {
- "version": "1.20.3",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
- "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
- "dependencies": {
- "bytes": "3.1.2",
- "content-type": "~1.0.5",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.13.0",
- "raw-body": "2.5.2",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/body-parser/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
+ "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
"license": "MIT",
"dependencies": {
- "ms": "2.0.0"
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.0",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.6.3",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.0",
+ "raw-body": "^3.0.0",
+ "type-is": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/body-parser/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/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -4210,9 +4202,9 @@
}
},
"node_modules/bson": {
- "version": "6.10.2",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.2.tgz",
- "integrity": "sha512-5afhLTjqDSA3akH56E+/2J6kTDuSIlBxyXPdQslj9hcIgOUE378xdOfZvC/9q3LifJNI6KR/juZ+d0NRNYBwXg==",
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.3.tgz",
+ "integrity": "sha512-MTxGsqgYTwfshYWTRdmZRC+M7FnG1b4y7RO7p2k3X24Wq0yv1m77Wsj0BzlPzd/IowgESfsruQCUToa7vbOpPQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=16.20.1"
@@ -4282,22 +4274,24 @@
}
},
"node_modules/cacheable": {
- "version": "1.8.7",
- "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.8.7.tgz",
- "integrity": "sha512-AbfG7dAuYNjYxFUtL1lAqmlWdxczCJ47w7cFjhGcnGnUdwSo6VgmSojfoW3tUI12HUkgTJ5kqj78yyq6TsFtlg==",
+ "version": "1.8.10",
+ "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.8.10.tgz",
+ "integrity": "sha512-0ZnbicB/N2R6uziva8l6O6BieBklArWyiGx4GkwAhLKhSHyQtRfM9T1nx7HHuHDKkYB/efJQhz3QJ6x/YqoZzA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "hookified": "^1.6.0",
- "keyv": "^5.2.3"
+ "hookified": "^1.8.1",
+ "keyv": "^5.3.2"
}
},
"node_modules/cacheable/node_modules/keyv": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.2.3.tgz",
- "integrity": "sha512-AGKecUfzrowabUv0bH1RIR5Vf7w+l4S3xtQAypKaUpTdIR1EbrAcTxHCrpo9Q+IWeUlFE2palRtgIQcgm+PQJw==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.2.tgz",
+ "integrity": "sha512-Lji2XRxqqa5Wg+CHLVfFKBImfJZ4pCSccu9eVWK6w4c2SDFLd8JAn1zqTuSFnsxb7ope6rMsnIHfp+eBbRBRZQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@keyv/serialize": "^1.0.2"
+ "@keyv/serialize": "^1.0.3"
}
},
"node_modules/cached-path-relative": {
@@ -4310,6 +4304,7 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0",
@@ -4324,9 +4319,10 @@
}
},
"node_modules/call-bind-apply-helpers": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
- "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
@@ -4336,12 +4332,13 @@
}
},
"node_modules/call-bound": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
- "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "get-intrinsic": "^1.2.6"
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
@@ -4371,9 +4368,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001699",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz",
- "integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==",
+ "version": "1.0.30001704",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001704.tgz",
+ "integrity": "sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==",
"funding": [
{
"type": "opencollective",
@@ -4546,6 +4543,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
@@ -4556,7 +4554,8 @@
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "license": "MIT"
},
"node_modules/colord": {
"version": "2.9.3",
@@ -4646,9 +4645,9 @@
"license": "MIT"
},
"node_modules/content-disposition": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
- "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
+ "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "5.2.1"
@@ -4726,22 +4725,23 @@
}
},
"node_modules/core-js": {
- "version": "3.40.0",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz",
- "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==",
+ "version": "3.41.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.41.0.tgz",
+ "integrity": "sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA==",
"hasInstallScript": true,
+ "license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/core-js-compat": {
- "version": "3.40.0",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz",
- "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==",
+ "version": "3.41.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz",
+ "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==",
"license": "MIT",
"dependencies": {
- "browserslist": "^4.24.3"
+ "browserslist": "^4.24.4"
},
"funding": {
"type": "opencollective",
@@ -4914,6 +4914,7 @@
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -4959,6 +4960,7 @@
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz",
"integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"mdn-data": "2.12.2",
"source-map-js": "^1.0.1"
@@ -5060,6 +5062,7 @@
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
"integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"es-errors": "^1.3.0",
@@ -5077,6 +5080,7 @@
"resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
"integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"es-errors": "^1.3.0",
@@ -5094,6 +5098,7 @@
"resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
"integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
@@ -5107,9 +5112,10 @@
}
},
"node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
@@ -5383,19 +5389,11 @@
"npm": ">=1.2"
}
},
- "node_modules/dompurify": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz",
- "integrity": "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==",
- "license": "(MPL-2.0 OR Apache-2.0)",
- "optionalDependencies": {
- "@types/trusted-types": "^2.0.7"
- }
- },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
@@ -5430,9 +5428,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
- "version": "1.5.97",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.97.tgz",
- "integrity": "sha512-HKLtaH02augM7ZOdYRuO19rWDeY+QSJ1VxnXFa/XDFLf07HvM90pALIJFgrO+UVaajI3+aJMMpojoUTLZyQ7JQ==",
+ "version": "1.5.118",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.118.tgz",
+ "integrity": "sha512-yNDUus0iultYyVoEFLnQeei7LOQkL8wg8GQpkPCRrOlJXlcCwa6eGKZkxQ9ciHsqZyYbj8Jd94X1CTPzGm+uIA==",
"license": "ISC"
},
"node_modules/elliptic": {
@@ -5534,6 +5532,7 @@
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.7.tgz",
"integrity": "sha512-OygGC8kIcDhXX+6yAZRGLqwi2CmEXCbLQixeGUgYeR+Qwlppqmo7DIDr8XibtEBZp+fJcoYpoatp5qwLMEdcqQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"array-buffer-byte-length": "^1.0.2",
"arraybuffer.prototype.slice": "^1.0.4",
@@ -5594,6 +5593,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
}
@@ -5612,6 +5612,7 @@
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz",
"integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.3",
@@ -5635,9 +5636,9 @@
}
},
"node_modules/es-object-atoms": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
- "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
@@ -5676,6 +5677,7 @@
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
"integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-callable": "^1.2.7",
"is-date-object": "^1.0.5",
@@ -5704,18 +5706,19 @@
"license": "MIT"
},
"node_modules/eslint": {
- "version": "9.21.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz",
- "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==",
+ "version": "9.24.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz",
+ "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.19.2",
+ "@eslint/config-array": "^0.20.0",
+ "@eslint/config-helpers": "^0.2.0",
"@eslint/core": "^0.12.0",
- "@eslint/eslintrc": "^3.3.0",
- "@eslint/js": "9.21.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.24.0",
"@eslint/plugin-kit": "^0.2.7",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
@@ -5727,7 +5730,7 @@
"cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.2.0",
+ "eslint-scope": "^8.3.0",
"eslint-visitor-keys": "^4.2.0",
"espree": "^10.3.0",
"esquery": "^1.5.0",
@@ -5768,6 +5771,7 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.11.0.tgz",
"integrity": "sha512-QAfipLcNCWLVocVbZW8GimKn5p5iiMcgGbRzz8z/P5q7xw+cNEpYqyzFMtIF/ZgF2HLOyy+dYBut+DoYolvqig==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
@@ -5789,10 +5793,11 @@
}
},
"node_modules/eslint-plugin-react": {
- "version": "7.37.4",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz",
- "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==",
+ "version": "7.37.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
+ "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"array-includes": "^3.1.8",
"array.prototype.findlast": "^1.2.5",
@@ -5804,7 +5809,7 @@
"hasown": "^2.0.2",
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
"minimatch": "^3.1.2",
- "object.entries": "^1.1.8",
+ "object.entries": "^1.1.9",
"object.fromentries": "^2.0.8",
"object.values": "^1.2.1",
"prop-types": "^15.8.1",
@@ -5852,10 +5857,11 @@
}
},
"node_modules/eslint-scope": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
- "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
+ "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
@@ -6008,6 +6014,7 @@
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
},
@@ -6152,45 +6159,41 @@
"license": "MIT"
},
"node_modules/express": {
- "version": "4.21.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
- "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
+ "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
"license": "MIT",
"dependencies": {
- "accepts": "~1.3.8",
- "array-flatten": "1.1.1",
- "body-parser": "1.20.3",
- "content-disposition": "0.5.4",
- "content-type": "~1.0.4",
- "cookie": "0.7.1",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.3.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "merge-descriptors": "1.0.3",
- "methods": "~1.1.2",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.12",
- "proxy-addr": "~2.0.7",
- "qs": "6.13.0",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.2.1",
- "send": "0.19.0",
- "serve-static": "1.16.2",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.0",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
},
"engines": {
- "node": ">= 0.10.0"
+ "node": ">= 18"
},
"funding": {
"type": "opencollective",
@@ -6207,33 +6210,87 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.2.0.tgz",
"integrity": "sha512-4ZQ0pHX0CAauxmzry2/8XFLM6aZA4NBvg9QezSlsEO1zLnl7vMFa48/WIcjzdfOiEUS4S1npPPKP2NHHYAp6qg==",
+ "license": "MIT",
"dependencies": {
"parseurl": "^1.3.3",
"serve-static": "^1.16.2"
}
},
- "node_modules/express/node_modules/cookie": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
- "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+ "node_modules/express/node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "node_modules/express/node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/express/node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
- "node_modules/express/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "node_modules/express/node_modules/mime-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
"license": "MIT",
"dependencies": {
- "ms": "2.0.0"
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
}
},
- "node_modules/express/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/express/node_modules/send": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
+ "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.5",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "mime-types": "^3.0.1",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/express/node_modules/serve-static": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
+ "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
},
"node_modules/extend": {
"version": "3.0.2",
@@ -6309,6 +6366,7 @@
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
@@ -6357,7 +6415,8 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
"integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
- "dev": true
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
@@ -6402,6 +6461,13 @@
"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",
@@ -6415,35 +6481,22 @@
}
},
"node_modules/finalhandler": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
- "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
+ "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
+ "license": "MIT",
"dependencies": {
- "debug": "2.6.9",
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "2.0.1",
- "unpipe": "~1.0.0"
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
},
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/finalhandler/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/finalhandler/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- },
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -6476,16 +6529,18 @@
}
},
"node_modules/flatted": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
- "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
- "dev": true
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-callable": "^1.1.3"
}
@@ -6560,6 +6615,7 @@
"version": "11.3.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
"integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+ "license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@@ -6575,6 +6631,20 @@
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"license": "ISC"
},
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -6589,6 +6659,7 @@
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
"integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.3",
@@ -6681,20 +6752,21 @@
}
},
"node_modules/get-intrinsic": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz",
- "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "dunder-proto": "^1.0.0",
+ "call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0",
+ "es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
- "math-intrinsics": "^1.0.0"
+ "math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -6713,6 +6785,19 @@
"node": ">=8.0.0"
}
},
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -6731,6 +6816,7 @@
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
"integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"es-errors": "^1.3.0",
@@ -6936,6 +7022,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -6976,6 +7063,7 @@
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
"integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -7009,6 +7097,7 @@
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
"integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.0"
},
@@ -7023,6 +7112,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -7164,10 +7254,11 @@
}
},
"node_modules/hookified": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.6.0.tgz",
- "integrity": "sha512-se7cpwTA+iA/eY548Bu03JJqBiEZAqU2jnyKdj5B5qurtBg64CZGHTgqCv4Yh7NWu6FGI09W61MCq+NoPj9GXA==",
- "dev": true
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.8.1.tgz",
+ "integrity": "sha512-GrO2l93P8xCWBSTBX9l2BxI78VU/MAAYag+pG8curS3aBGy0++ZlxrQ7PdUOUVMbn5BwkGb6+eRrnf43ipnFEA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/html-encoding-sniffer": {
"version": "4.0.0",
@@ -7273,12 +7364,12 @@
}
},
"node_modules/iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "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",
"dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
@@ -7464,6 +7555,7 @@
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
"integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"hasown": "^2.0.2",
@@ -7499,6 +7591,7 @@
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
"integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.3",
@@ -7523,6 +7616,7 @@
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
"integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-tostringtag": "^1.0.0"
},
@@ -7538,6 +7632,7 @@
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
"integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-bigints": "^1.0.2"
},
@@ -7565,6 +7660,7 @@
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz",
"integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"has-tostringtag": "^1.0.2"
@@ -7587,6 +7683,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"
},
@@ -7626,6 +7723,7 @@
"resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
"integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"get-intrinsic": "^1.2.6",
@@ -7643,6 +7741,7 @@
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"has-tostringtag": "^1.0.2"
@@ -7690,6 +7789,7 @@
"resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
"integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3"
},
@@ -7724,6 +7824,7 @@
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
"integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-tostringtag": "^1.0.0"
},
@@ -7751,6 +7852,7 @@
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
"integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -7772,6 +7874,7 @@
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
"integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"has-tostringtag": "^1.0.2"
@@ -7801,11 +7904,18 @@
"license": "MIT",
"peer": true
},
+ "node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "license": "MIT"
+ },
"node_modules/is-regex": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"gopd": "^1.2.0",
@@ -7824,6 +7934,7 @@
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
"integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -7836,6 +7947,7 @@
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
"integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3"
},
@@ -7863,6 +7975,7 @@
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
"integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"has-tostringtag": "^1.0.2"
@@ -7879,6 +7992,7 @@
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
"integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"has-symbols": "^1.1.0",
@@ -7896,6 +8010,7 @@
"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"
},
@@ -7911,6 +8026,7 @@
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
"integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -7923,6 +8039,7 @@
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz",
"integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2"
},
@@ -7938,6 +8055,7 @@
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
"integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"get-intrinsic": "^1.2.6"
@@ -7968,7 +8086,8 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/isexe": {
"version": "2.0.0",
@@ -8098,6 +8217,7 @@
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.4.tgz",
"integrity": "sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"define-data-property": "^1.1.4",
"es-object-atoms": "^1.0.0",
@@ -9781,7 +9901,8 @@
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
"integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/loose-envify": {
"version": "1.4.0",
@@ -9865,9 +9986,9 @@
}
},
"node_modules/marked": {
- "version": "13.0.3",
- "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz",
- "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==",
+ "version": "15.0.8",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.8.tgz",
+ "integrity": "sha512-rli4l2LyZqpQuRve5C0rkn6pj3hT8EWPC+zkAxFTAJLxRbENfTAhEQq9itrmf1Y81QtAX5D/MYlGlIomNgj9lA==",
"license": "MIT",
"bin": {
"marked": "bin/marked.js"
@@ -9876,10 +9997,10 @@
"node": ">= 18"
}
},
- "node_modules/marked-definition-lists": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/marked-definition-lists/-/marked-definition-lists-1.0.1.tgz",
- "integrity": "sha512-+fBAbGbVnGNNkCLMTnieReZ+gq14iCF0rBc1BBMGDDqnKeImxdvoV9kB8xRTVW4ZH5BPp6XLVykUZW0icsvZTw==",
+ "node_modules/marked-alignment-paragraphs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/marked-alignment-paragraphs/-/marked-alignment-paragraphs-1.0.0.tgz",
+ "integrity": "sha512-e+X+vUt9oteG4I0+29ZvTjrNEvB2/uo/Dhczu+Nq0shITA3oqYmTercT25mq+2mfJQQn7xiJGXPmDmBSFgotIA==",
"license": "MIT",
"peerDependencies": {
"marked": ">=3 <16"
@@ -9895,9 +10016,9 @@
}
},
"node_modules/marked-extended-tables": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-2.0.0.tgz",
- "integrity": "sha512-MWmxvFLkJYQ5K46MFieOP1uueMgfIpDPMkYLLgIyTl20HyvLIW4J37BAtIGfR8fDp2uE4Kyyev4s3dhoT2FQOA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-2.0.1.tgz",
+ "integrity": "sha512-DV4Si978ZdaFbycIxzG4TdaNMtC0J8QfIKj1UOCejgJHwVjVJse8DNdJriWDeo/n74DWVYpRC6S56AdgWDPrPA==",
"license": "MIT",
"peerDependencies": {
"marked": ">=3 <16"
@@ -9915,6 +10036,15 @@
"marked": ">=13 <16"
}
},
+ "node_modules/marked-nonbreaking-spaces": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/marked-nonbreaking-spaces/-/marked-nonbreaking-spaces-1.0.1.tgz",
+ "integrity": "sha512-CUeFRc6OdMMSJThgOM7WAkUjL59VfSf79urKyKYtH9fs3hnrhC3+syFBimYh4vpvUZmjnXoZX0K6V3vZKmyRWQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "marked": ">=3 <16"
+ }
+ },
"node_modules/marked-smartypants-lite": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/marked-smartypants-lite/-/marked-smartypants-lite-1.0.3.tgz",
@@ -9950,6 +10080,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
}
@@ -9980,15 +10111,16 @@
"version": "2.12.2",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
"integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
- "dev": true
+ "dev": true,
+ "license": "CC0-1.0"
},
"node_modules/media-typer": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
"license": "MIT",
"engines": {
- "node": ">= 0.6"
+ "node": ">= 0.8"
}
},
"node_modules/memory-pager": {
@@ -10011,9 +10143,13 @@
}
},
"node_modules/merge-descriptors": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
- "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
@@ -10254,9 +10390,9 @@
}
},
"node_modules/mongodb-connection-string-url/node_modules/tr46": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz",
- "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.0.tgz",
+ "integrity": "sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==",
"license": "MIT",
"dependencies": {
"punycode": "^2.3.1"
@@ -10275,12 +10411,12 @@
}
},
"node_modules/mongodb-connection-string-url/node_modules/whatwg-url": {
- "version": "14.1.1",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.1.tgz",
- "integrity": "sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==",
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
"license": "MIT",
"dependencies": {
- "tr46": "^5.0.0",
+ "tr46": "^5.1.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
@@ -10288,14 +10424,14 @@
}
},
"node_modules/mongoose": {
- "version": "8.11.0",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.11.0.tgz",
- "integrity": "sha512-xaQSuaLk2JKmXI5zDVVWXVCQTnWhAe8MFOijMnwOuP/wucKVphd3f+ouDKivCDMGjYBDrR7dtoyV0U093xbKqA==",
+ "version": "8.13.2",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.13.2.tgz",
+ "integrity": "sha512-riCBqZmNkYBWjXpM3qWLDQw7QmTKsVZDPhLXFJqC87+OjocEVpvS3dA2BPPUiLAu+m0/QmEj5pSXKhH+/DgerQ==",
"license": "MIT",
"dependencies": {
- "bson": "^6.10.1",
+ "bson": "^6.10.3",
"kareem": "2.6.3",
- "mongodb": "~6.13.0",
+ "mongodb": "~6.15.0",
"mpath": "0.9.0",
"mquery": "5.0.0",
"ms": "2.1.3",
@@ -10371,13 +10507,13 @@
}
},
"node_modules/mongoose/node_modules/mongodb": {
- "version": "6.13.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.13.0.tgz",
- "integrity": "sha512-KeESYR5TEaFxOuwRqkOm3XOsMqCSkdeDMjaW5u2nuKfX7rqaofp7JQGoi7sVqQcNJTKuveNbzZtWMstb8ABP6Q==",
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.15.0.tgz",
+ "integrity": "sha512-ifBhQ0rRzHDzqp9jAQP6OwHSH7dbYIQjD3SbJs9YYk9AikKEettW/9s/tbSFDTpXcRbF+u1aLrhHxDFaYtZpFQ==",
"license": "Apache-2.0",
"dependencies": {
"@mongodb-js/saslprep": "^1.1.9",
- "bson": "^6.10.1",
+ "bson": "^6.10.3",
"mongodb-connection-string-url": "^3.0.0"
},
"engines": {
@@ -10442,10 +10578,17 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
+ "node_modules/nan": {
+ "version": "2.20.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz",
+ "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/nanoid": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.2.tgz",
- "integrity": "sha512-b+CiXQCNMUGe0Ri64S9SXFcP9hogjAJ2Rd6GdVxhPLRm7mhGaM7VgOvCAJ1ZshfHbqVDI3uqTI5C8/GaKuLI7g==",
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
+ "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==",
"funding": [
{
"type": "github",
@@ -10560,9 +10703,9 @@
"license": "MIT"
},
"node_modules/nconf": {
- "version": "0.12.1",
- "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.12.1.tgz",
- "integrity": "sha512-p2cfF+B3XXacQdswUYWZ0w6Vld0832A/tuqjLBu3H1sfUcby4N2oVbGhyuCkZv+t3iY3aiFEj7gZGqax9Q2c1w==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.13.0.tgz",
+ "integrity": "sha512-hJ/u2xCpA663h6xyOiztx3y+lg9eU0rdkwJ+c4FtiHo2g/gB0sjXtW31yTdMLWLOIj1gL2FcJMwfOqouuUK/Wg==",
"license": "MIT",
"dependencies": {
"async": "^3.0.0",
@@ -10613,9 +10756,9 @@
}
},
"node_modules/negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -10769,6 +10912,7 @@
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -10801,6 +10945,7 @@
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
"integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.3",
@@ -10817,15 +10962,16 @@
}
},
"node_modules/object.entries": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz",
- "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==",
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz",
+ "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
"define-properties": "^1.2.1",
- "es-object-atoms": "^1.0.0"
+ "es-object-atoms": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
@@ -10867,6 +11013,7 @@
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
"integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.3",
@@ -11151,10 +11298,13 @@
}
},
"node_modules/path-to-regexp": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
- "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
- "license": "MIT"
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
+ "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
},
"node_modules/path-type": {
"version": "4.0.0",
@@ -11303,14 +11453,15 @@
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/postcss": {
- "version": "8.5.1",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
- "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==",
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
"dev": true,
"funding": [
{
@@ -11587,11 +11738,12 @@
"license": "MIT"
},
"node_modules/qs": {
- "version": "6.13.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
- "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "license": "BSD-3-Clause",
"dependencies": {
- "side-channel": "^1.0.6"
+ "side-channel": "^1.1.0"
},
"engines": {
"node": ">=0.6"
@@ -11658,14 +11810,14 @@
}
},
"node_modules/raw-body": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
- "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
+ "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
+ "iconv-lite": "0.6.3",
"unpipe": "1.0.0"
},
"engines": {
@@ -11716,9 +11868,9 @@
"license": "MIT"
},
"node_modules/react-router": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.2.0.tgz",
- "integrity": "sha512-fXyqzPgCPZbqhrk7k3hPcCpYIlQ2ugIXDboHUzhJISFVy2DEPsmHgN588MyGmkIOv3jDgNfUE3kJi83L28s/LQ==",
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.0.tgz",
+ "integrity": "sha512-estOHrRlDMKdlQa6Mj32gIks4J+AxNsYoE0DbTTxiMy2mPzZuWSDU+N85/r1IlNR7kGfznF3VCUlvc5IUO+B9g==",
"license": "MIT",
"dependencies": {
"@types/cookie": "^0.6.0",
@@ -11810,6 +11962,7 @@
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz",
"integrity": "sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
@@ -11911,6 +12064,7 @@
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
"integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
@@ -11994,6 +12148,7 @@
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -12095,6 +12250,28 @@
"inherits": "^2.0.1"
}
},
+ "node_modules/romans": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/romans/-/romans-3.0.0.tgz",
+ "integrity": "sha512-7DDsAfhtpRr/ZFQXiHDrC3Pe00agcAsFiNt5nNx4ZAQlsc6yJG0mvXA5WAvO8YZyOg349twm2GYhHLw7rCXAzw==",
+ "license": "MIT"
+ },
+ "node_modules/router": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
"node_modules/rrweb-cssom": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
@@ -12132,6 +12309,7 @@
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
"integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.2",
@@ -12180,6 +12358,7 @@
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
"integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
@@ -12443,6 +12622,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
@@ -12461,6 +12641,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
@@ -12476,6 +12657,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
@@ -12493,6 +12675,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
@@ -12583,6 +12766,7 @@
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
"integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"astral-regex": "^2.0.0",
@@ -12959,6 +13143,7 @@
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
"integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.3",
@@ -12997,6 +13182,7 @@
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
"integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.2",
@@ -13018,6 +13204,7 @@
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
"integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.2",
@@ -13102,9 +13289,9 @@
"license": "ISC"
},
"node_modules/stylelint": {
- "version": "16.14.1",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.14.1.tgz",
- "integrity": "sha512-oqCL7AC3786oTax35T/nuLL8p2C3k/8rHKAooezrPGRvUX0wX+qqs5kMWh5YYT4PHQgVDobHT4tw55WgpYG6Sw==",
+ "version": "16.18.0",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.18.0.tgz",
+ "integrity": "sha512-OXb68qzesv7J70BSbFwfK3yTVLEVXiQ/ro6wUE4UrSbKCMjLLA02S8Qq3LC01DxKyVjk7z8xh35aB4JzO3/sNA==",
"dev": true,
"funding": [
{
@@ -13131,7 +13318,7 @@
"debug": "^4.3.7",
"fast-glob": "^3.3.3",
"fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^10.0.5",
+ "file-entry-cache": "^10.0.7",
"global-modules": "^2.0.0",
"globby": "^11.1.0",
"globjoin": "^0.1.4",
@@ -13145,14 +13332,14 @@
"micromatch": "^4.0.8",
"normalize-path": "^3.0.0",
"picocolors": "^1.1.1",
- "postcss": "^8.5.1",
+ "postcss": "^8.5.3",
"postcss-resolve-nested-selector": "^0.1.6",
"postcss-safe-parser": "^7.0.1",
- "postcss-selector-parser": "^7.0.0",
+ "postcss-selector-parser": "^7.1.0",
"postcss-value-parser": "^4.2.0",
"resolve-from": "^5.0.0",
"string-width": "^4.2.3",
- "supports-hyperlinks": "^3.1.0",
+ "supports-hyperlinks": "^3.2.0",
"svg-tags": "^1.0.0",
"table": "^6.9.0",
"write-file-atomic": "^5.0.1"
@@ -13169,6 +13356,7 @@
"resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-6.0.0.tgz",
"integrity": "sha512-1KqrttqpIrCYFAVQ1/bbgXo7EvvcjmkxxmnzVr+U66Xr2OlrNZqQ5+44Tmct6grCWY6wGTIBh2tSANqcmwIM2g==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"stylelint-order": "^6.0.4"
},
@@ -13177,9 +13365,9 @@
}
},
"node_modules/stylelint-config-recommended": {
- "version": "15.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-15.0.0.tgz",
- "integrity": "sha512-9LejMFsat7L+NXttdHdTq94byn25TD+82bzGRiV1Pgasl99pWnwipXS5DguTpp3nP1XjvLXVnEJIuYBfsRjRkA==",
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-16.0.0.tgz",
+ "integrity": "sha512-4RSmPjQegF34wNcK1e1O3Uz91HN8P1aFdFzio90wNK9mjgAI19u5vsU868cVZboKzCaa5XbpvtTzAAGQAxpcXA==",
"dev": true,
"funding": [
{
@@ -13191,11 +13379,12 @@
"url": "https://github.com/sponsors/stylelint"
}
],
+ "license": "MIT",
"engines": {
"node": ">=18.12.0"
},
"peerDependencies": {
- "stylelint": "^16.13.0"
+ "stylelint": "^16.16.0"
}
},
"node_modules/stylelint-order": {
@@ -13267,23 +13456,25 @@
"license": "MIT"
},
"node_modules/stylelint/node_modules/file-entry-cache": {
- "version": "10.0.5",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.0.5.tgz",
- "integrity": "sha512-umpQsJrBNsdMDgreSryMEXvJh66XeLtZUwA8Gj7rHGearGufUFv6rB/bcXRFsiGWw/VeSUgUofF4Rf2UKEOrTA==",
+ "version": "10.0.8",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.0.8.tgz",
+ "integrity": "sha512-FGXHpfmI4XyzbLd3HQ8cbUcsFGohJpZtmQRHr8z8FxxtCe2PcpgIlVLwIgunqjvRmXypBETvwhV4ptJizA+Y1Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "flat-cache": "^6.1.5"
+ "flat-cache": "^6.1.8"
}
},
"node_modules/stylelint/node_modules/flat-cache": {
- "version": "6.1.5",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.5.tgz",
- "integrity": "sha512-QR+2kN38f8nMfiIQ1LHYjuDEmZNZVjxuxY+HufbS3BW0EX01Q5OnH7iduOYRutmgiXb797HAKcXUeXrvRjjgSQ==",
+ "version": "6.1.8",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.8.tgz",
+ "integrity": "sha512-R6MaD3nrJAtO7C3QOuS79ficm2pEAy++TgEUD8ii1LVlbcgZ9DtASLkt9B+RZSFCzm7QHDMlXPsqqB6W2Pfr1Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "cacheable": "^1.8.7",
- "flatted": "^3.3.2",
- "hookified": "^1.6.0"
+ "cacheable": "^1.8.9",
+ "flatted": "^3.3.3",
+ "hookified": "^1.8.1"
}
},
"node_modules/stylelint/node_modules/ignore": {
@@ -13291,14 +13482,15 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz",
"integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/stylelint/node_modules/postcss-selector-parser": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz",
- "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13356,9 +13548,10 @@
}
},
"node_modules/superagent": {
- "version": "10.1.1",
- "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.1.1.tgz",
- "integrity": "sha512-9pIwrHrOj3uAnqg9gDlW7EA2xv+N5au/dSM0kM22HTqmUu8jBxNT+8uA7tA3UoCnmiqzpSbu8rasIUZvbyamMQ==",
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.0.tgz",
+ "integrity": "sha512-IKeoGox6oG9zyDeizaezkJ2/aK0wc5la9st7WsAKyrAkfJ56W3whVbVtF68k6wuc87/y9T85NyON5FLz7Mrzzw==",
+ "license": "MIT",
"dependencies": {
"component-emitter": "^1.3.0",
"cookiejar": "^2.1.4",
@@ -13387,9 +13580,9 @@
}
},
"node_modules/supertest": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz",
- "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.0.tgz",
+ "integrity": "sha512-5QeSO8hSrKghtcWEoPiO036fxH0Ii2wVQfFZSP0oqQhmjk8bOLhDFXr4JrvaFmPuEWUoq4znY3uSi8UzLKxGqw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13445,10 +13638,11 @@
}
},
"node_modules/supports-hyperlinks": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz",
- "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz",
+ "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0",
"supports-color": "^7.0.0"
@@ -13457,7 +13651,7 @@
"node": ">=14.18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1"
}
},
"node_modules/supports-hyperlinks/node_modules/has-flag": {
@@ -13465,6 +13659,7 @@
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -13474,6 +13669,7 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -13521,6 +13717,7 @@
"resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz",
"integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"ajv": "^8.0.1",
"lodash.truncate": "^4.4.2",
@@ -13537,6 +13734,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -13552,7 +13750,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/test-exclude": {
"version": "6.0.0",
@@ -13854,13 +14053,35 @@
}
},
"node_modules/type-is": {
- "version": "1.6.18",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
- "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
"license": "MIT",
"dependencies": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
+ "content-type": "^1.0.5",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/type-is/node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/type-is/node_modules/mime-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
},
"engines": {
"node": ">= 0.6"
@@ -13871,6 +14092,7 @@
"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",
"es-errors": "^1.3.0",
@@ -13885,6 +14107,7 @@
"resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
"integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"for-each": "^0.3.3",
@@ -13904,6 +14127,7 @@
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
"integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.8",
@@ -13925,6 +14149,7 @@
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
"integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
@@ -13975,6 +14200,7 @@
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
"integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"has-bigints": "^1.0.2",
@@ -14151,9 +14377,9 @@
}
},
"node_modules/update-browserslist-db": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
- "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
"funding": [
{
"type": "opencollective",
@@ -14258,15 +14484,6 @@
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
"license": "ISC"
},
- "node_modules/utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4.0"
- }
- },
"node_modules/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
@@ -14502,6 +14719,25 @@
"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": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2",
+ "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",
@@ -14691,20 +14927,6 @@
"node": ">=18"
}
},
- "node_modules/whatwg-encoding/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==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/whatwg-mimetype": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
@@ -14747,6 +14969,7 @@
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
"integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-bigint": "^1.1.0",
"is-boolean-object": "^1.2.1",
@@ -14766,6 +14989,7 @@
"resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
"integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"function.prototype.name": "^1.1.6",
@@ -14793,6 +15017,7 @@
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
"integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-map": "^2.0.3",
"is-set": "^2.0.3",
@@ -14811,6 +15036,7 @@
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz",
"integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.8",
@@ -14873,6 +15099,12 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
+ "node_modules/written-number": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/written-number/-/written-number-0.11.1.tgz",
+ "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",
diff --git a/package.json b/package.json
index d54781080..8b817cfd3 100644
--- a/package.json
+++ b/package.json
@@ -1,10 +1,10 @@
{
"name": "homebrewery",
"description": "Create authentic looking D&D homebrews using only markdown",
- "version": "3.17.0",
+ "version": "3.18.1",
"type": "module",
"engines": {
- "npm": "^10.2.x",
+ "npm": "^10.8.x",
"node": "^20.18.x"
},
"repository": {
@@ -83,22 +83,21 @@
]
},
"dependencies": {
- "@babel/core": "^7.26.9",
- "@babel/plugin-transform-runtime": "^7.26.9",
+ "@babel/core": "^7.26.10",
+ "@babel/plugin-transform-runtime": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.26.3",
- "@googleapis/drive": "^8.16.0",
- "body-parser": "^1.20.2",
+ "@googleapis/drive": "^11.0.0",
+ "body-parser": "^2.2.0",
"classnames": "^2.5.1",
"codemirror": "^5.65.6",
"cookie-parser": "^1.4.7",
- "core-js": "^3.40.0",
+ "core-js": "^3.41.0",
"cors": "^2.8.5",
"create-react-class": "^15.7.0",
"dedent-tabs": "^0.10.3",
- "dompurify": "^3.2.4",
"expr-eval": "^2.0.2",
- "express": "^4.21.2",
+ "express": "^5.1.0",
"express-async-handler": "^1.2.0",
"express-static-gzip": "2.2.0",
"fs-extra": "11.3.0",
@@ -107,40 +106,44 @@
"jwt-simple": "^0.5.6",
"less": "^3.13.1",
"lodash": "^4.17.21",
- "marked": "13.0.3",
- "marked-definition-lists": "^1.0.1",
+ "marked": "15.0.8",
+ "marked-definition-lists": "^1.0.1",
"marked-emoji": "^2.0.0",
- "marked-extended-tables": "^2.0.0",
+ "marked-extended-tables": "^2.0.1",
"marked-gfm-heading-id": "^4.0.1",
+ "marked-alignment-paragraphs": "^1.0.0",
+ "marked-nonbreaking-spaces": "^1.0.1",
"marked-smartypants-lite": "^1.0.3",
"marked-subsuper-text": "^1.0.3",
"markedLegacy": "npm:marked@^0.3.19",
"moment": "^2.30.1",
- "mongoose": "^8.11.0",
- "nanoid": "5.1.2",
- "nconf": "^0.12.1",
+ "mongoose": "^8.13.2",
+ "nanoid": "5.1.5",
+ "nconf": "^0.13.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-frame-component": "^4.1.3",
- "react-router": "^7.2.0",
+ "react-router": "^7.5.0",
+ "romans": "^3.0.0",
"sanitize-filename": "1.6.3",
- "superagent": "^10.1.1",
- "vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
+ "superagent": "^10.2.0",
+ "vitreum": "git+https://git@github.com/calculuschild/vitreum.git",
+ "written-number": "^0.11.1"
},
"devDependencies": {
"@stylistic/stylelint-plugin": "^3.1.2",
"babel-plugin-transform-import-meta": "^2.3.2",
- "eslint": "^9.21.0",
+ "eslint": "^9.24.0",
"eslint-plugin-jest": "^28.11.0",
- "eslint-plugin-react": "^7.37.4",
+ "eslint-plugin-react": "^7.37.5",
"globals": "^16.0.0",
"jest": "^29.7.0",
"jest-expect-message": "^1.1.3",
"jsdom-global": "^3.0.2",
"postcss-less": "^6.0.0",
- "stylelint": "^16.14.1",
+ "stylelint": "^16.18.0",
"stylelint-config-recess-order": "^6.0.0",
- "stylelint-config-recommended": "^15.0.0",
- "supertest": "^7.0.0"
+ "stylelint-config-recommended": "^16.0.0",
+ "supertest": "^7.1.0"
}
}
diff --git a/scripts/buildHomebrew.js b/scripts/buildHomebrew.js
index 656714d87..4d55a4176 100644
--- a/scripts/buildHomebrew.js
+++ b/scripts/buildHomebrew.js
@@ -10,7 +10,7 @@ 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 isDev = !!process.argv.find((arg)=>arg === '--dev');
const babelify = async (code)=>(await babel.transformAsync(code, babelConfig)).code;
@@ -53,7 +53,7 @@ fs.emptyDirSync('./build');
const themes = { Legacy: {}, V3: {} };
let themeFiles = fs.readdirSync('./themes/Legacy');
- for (let dir of themeFiles) {
+ for (const dir of themeFiles) {
const themeData = JSON.parse(fs.readFileSync(`./themes/Legacy/${dir}/settings.json`).toString());
themeData.path = dir;
themes.Legacy[dir] = (themeData);
@@ -70,7 +70,7 @@ fs.emptyDirSync('./build');
}
themeFiles = fs.readdirSync('./themes/V3');
- for (let dir of themeFiles) {
+ for (const dir of themeFiles) {
const themeData = JSON.parse(fs.readFileSync(`./themes/V3/${dir}/settings.json`).toString());
themeData.path = dir;
themes.V3[dir] = (themeData);
@@ -113,7 +113,7 @@ fs.emptyDirSync('./build');
const stream = fs.createWriteStream(editorThemeFile, { flags: 'a' });
stream.write('[\n"default"');
- for (let themeFile of editorThemeFiles) {
+ for (const themeFile of editorThemeFiles) {
stream.write(`,\n"${themeFile.slice(0, -4)}"`);
}
stream.write('\n]\n');
diff --git a/server/admin.api.js b/server/admin.api.js
index e70268afa..a3d7622f1 100644
--- a/server/admin.api.js
+++ b/server/admin.api.js
@@ -1,3 +1,4 @@
+/*eslint max-lines: ["warn", {"max": 500, "skipBlankLines": true, "skipComments": true}]*/
import { model as HomebrewModel } from './homebrew.model.js';
import { model as NotificationModel } from './notifications.model.js';
import express from 'express';
@@ -11,6 +12,7 @@ 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';
@@ -162,6 +164,180 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{
}
});
+// ####################### LOCKS
+
+router.get('/api/lock/count', mw.adminOnly, asyncHandler(async (req, res)=>{
+
+ 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 });
+
+}));
+
+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
+ }
+ }
+ ];
+ 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
+ });
+
+}));
+
+router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{
+
+ const lock = req.body;
+
+ lock.applied = new Date;
+
+ const filter = {
+ shareId : req.params.id
+ };
+
+ 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.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;
+
+ brew.lock = lock;
+ brew.markModified('lock');
+
+ 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 });
+
+}));
+
+router.put('/api/unlock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{
+
+ const filter = {
+ shareId : req.params.id
+ };
+
+ 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.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');
+
+ 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}` });
+}));
+
+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
+ }
+ }
+ ];
+ 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
+ });
+
+}));
+
+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 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' };
+ };
+
+ brew.lock.reviewRequested = new Date();
+ brew.markModified('lock');
+
+ 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}` });
+
+}));
+
+router.put('/api/lock/review/remove/:id', mw.adminOnly, asyncHandler(async (req, res)=>{
+
+ 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' }; };
+
+ brew.lock.reviewRequested = undefined;
+ brew.markModified('lock');
+
+ 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}` });
+
+}));
+
// ####################### NOTIFICATIONS
router.get('/admin/notification/all', async (req, res, next)=>{
diff --git a/server/admin.api.spec.js b/server/admin.api.spec.js
index 6a23393b1..e156c6c8f 100644
--- a/server/admin.api.spec.js
+++ b/server/admin.api.spec.js
@@ -1,6 +1,8 @@
+/*eslint max-lines: ["warn", {"max": 1000, "skipBlankLines": true, "skipComments": true}]*/
import supertest from 'supertest';
import HBApp from './app.js';
-import {model as NotificationModel } from './notifications.model.js';
+import { model as NotificationModel } from './notifications.model.js';
+import { model as HomebrewModel } from './homebrew.model.js';
// Mimic https responses to avoid being redirected all the time
@@ -16,7 +18,7 @@ describe('Tests for admin api', ()=>{
const testNotifications = ['a', 'b'];
jest.spyOn(NotificationModel, 'find')
- .mockImplementationOnce(() => {
+ .mockImplementationOnce(()=>{
return { exec: jest.fn().mockResolvedValue(testNotifications) };
});
@@ -59,7 +61,7 @@ describe('Tests for admin api', ()=>{
expect(response.body).toEqual(savedNotification);
});
- it('should handle error adding a notification without dismissKey', async () => {
+ it('should handle error adding a notification without dismissKey', async ()=>{
const inputNotification = {
title : 'Test Notification',
text : 'This is a test notification',
@@ -75,7 +77,7 @@ describe('Tests for admin api', ()=>{
const response = await app
.post('/admin/notification/add')
- .set('Authorization', 'Basic ' + Buffer.from('admin:password3').toString('base64'))
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
.send(inputNotification);
expect(response.status).toBe(500);
@@ -86,14 +88,14 @@ describe('Tests for admin api', ()=>{
const dismissKey = 'testKey';
jest.spyOn(NotificationModel, 'findOneAndDelete')
- .mockImplementationOnce((key) => {
+ .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')}`);
- expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({'dismissKey': 'testKey'});
+ expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ 'dismissKey': 'testKey' });
expect(response.status).toBe(200);
expect(response.body).toEqual({ dismissKey: 'testKey' });
});
@@ -102,16 +104,602 @@ describe('Tests for admin api', ()=>{
const dismissKey = 'testKey';
jest.spyOn(NotificationModel, 'findOneAndDelete')
- .mockImplementationOnce(() => {
+ .mockImplementationOnce(()=>{
return { exec: jest.fn().mockResolvedValue() };
});
const response = await app
.delete(`/admin/notification/delete/${dismissKey}`)
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`);
- expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({'dismissKey': 'testKey'});
+ expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ 'dismissKey': 'testKey' });
expect(response.status).toBe(500);
expect(response.body).toEqual({ message: 'Notification not found' });
});
});
+
+ describe('Locks', ()=>{
+ describe('Count', ()=>{
+ it('Count of all locked documents', async ()=>{
+ const testNumber = 16777216; // 8^8, because why not
+
+ jest.spyOn(HomebrewModel, 'countDocuments')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testNumber);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .get('/api/lock/count');
+
+ 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();
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .get('/api/lock/count');
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '61',
+ message : 'Unable to get lock count',
+ name : 'Lock Count Error',
+ originalUrl : '/api/lock/count',
+ status : 500,
+ });
+ });
+ });
+
+ describe('Lists', ()=>{
+ it('Get list of all locked documents', async ()=>{
+ const testLocks = ['a', 'b'];
+
+ jest.spyOn(HomebrewModel, 'aggregate')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testLocks);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .get('/api/locks');
+
+ 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();
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .get('/api/locks');
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '68',
+ message : 'Unable to get locked brew collection',
+ name : 'Can Not Get Locked Brews',
+ originalUrl : '/api/locks',
+ status : 500
+ });
+ });
+
+ 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);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .get('/api/lock/reviews');
+
+ 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();
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .get('/api/lock/reviews');
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '68',
+ message : 'Unable to get review collection',
+ name : 'Can Not Get Reviews',
+ originalUrl : '/api/lock/reviews',
+ status : 500
+ });
+ });
+ });
+
+ describe('Lock', ()=>{
+ it('Lock a brew', async ()=>{
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.resolve(); }
+ };
+
+ const testLock = {
+ code : 999,
+ editMessage : 'edit',
+ shareMessage : 'share'
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .post(`/api/lock/${testBrew.shareId}`)
+ .send(testLock);
+
+ expect(response.status).toBe(200);
+ expect(response.body).toMatchObject({
+ applied : expect.any(String),
+ code : testLock.code,
+ editMessage : testLock.editMessage,
+ shareMessage : testLock.shareMessage,
+ name : 'LOCKED',
+ message : `Lock applied to brew ID ${testBrew.shareId} - ${testBrew.title}`
+ });
+ });
+
+ it('Overwrite lock on a locked brew', async ()=>{
+ const testLock = {
+ code : 999,
+ editMessage : 'newEdit',
+ shareMessage : 'newShare',
+ overwrite : true
+ };
+
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.resolve(); },
+ lock : {
+ code : 1,
+ editMessage : 'oldEdit',
+ shareMessage : 'oldShare',
+ }
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .post(`/api/lock/${testBrew.shareId}`)
+ .send(testLock);
+
+ expect(response.status).toBe(200);
+ expect(response.body).toMatchObject({
+ applied : expect.any(String),
+ code : testLock.code,
+ editMessage : testLock.editMessage,
+ shareMessage : testLock.shareMessage,
+ name : 'LOCKED',
+ message : `Lock applied to brew ID ${testBrew.shareId} - ${testBrew.title}`
+ });
+ });
+
+ it('Error when locking a locked brew', async ()=>{
+ const testLock = {
+ code : 999,
+ editMessage : 'newEdit',
+ shareMessage : 'newShare'
+ };
+
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.resolve(); },
+ lock : {
+ code : 1,
+ editMessage : 'oldEdit',
+ shareMessage : 'oldShare',
+ }
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .post(`/api/lock/${testBrew.shareId}`)
+ .send(testLock);
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '64',
+ message : 'Lock already exists on brew',
+ name : 'Already Locked',
+ originalUrl : `/api/lock/${testBrew.shareId}`,
+ shareId : testBrew.shareId,
+ status : 500,
+ title : 'title'
+ });
+ });
+
+ it('Handle save error while locking a brew', async ()=>{
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.reject(); }
+ };
+
+ const testLock = {
+ code : 999,
+ editMessage : 'edit',
+ shareMessage : 'share'
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .post(`/api/lock/${testBrew.shareId}`)
+ .send(testLock);
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '62',
+ message : 'Unable to set lock',
+ name : 'Lock Error',
+ originalUrl : `/api/lock/${testBrew.shareId}`,
+ shareId : testBrew.shareId,
+ status : 500
+ });
+ });
+ });
+
+ describe('Unlock', ()=>{
+ it('Unlock a brew', async ()=>{
+ const testLock = {
+ applied : 'YES',
+ code : 999,
+ editMessage : 'edit',
+ shareMessage : 'share'
+ };
+
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.resolve(); },
+ lock : testLock
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .put(`/api/unlock/${testBrew.shareId}`);
+
+ expect(response.status).toBe(200);
+ expect(response.body).toEqual({
+ name : 'Unlocked',
+ message : `Lock removed from brew ID ${testBrew.shareId}`
+ });
+ });
+
+ it('Error when unlocking a brew with no lock', async ()=>{
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.resolve(); },
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .put(`/api/unlock/${testBrew.shareId}`);
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '67',
+ message : 'Cannot unlock as brew is not locked',
+ name : 'Not Locked',
+ originalUrl : `/api/unlock/${testBrew.shareId}`,
+ shareId : testBrew.shareId,
+ status : 500,
+ });
+ });
+
+ it('Handle error while unlocking a brew', async ()=>{
+ const testLock = {
+ applied : 'YES',
+ code : 999,
+ editMessage : 'edit',
+ shareMessage : 'share'
+ };
+
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.reject(); },
+ lock : testLock
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .put(`/api/unlock/${testBrew.shareId}`);
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '65',
+ message : 'Unable to clear lock',
+ name : 'Cannot Unlock',
+ originalUrl : `/api/unlock/${testBrew.shareId}`,
+ shareId : testBrew.shareId,
+ status : 500
+ });
+ });
+ });
+
+ describe('Reviews', ()=>{
+ it('Add review request to a locked brew', async ()=>{
+ const testLock = {
+ applied : 'YES',
+ code : 999,
+ editMessage : 'edit',
+ shareMessage : 'share'
+ };
+
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.resolve(); },
+ lock : testLock
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .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',
+ });
+ });
+
+ it('Error when cannot find a locked brew', async ()=>{
+ const testBrew = {
+ shareId : 'shareId'
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(false);
+ });
+
+
+ const response = await app
+ .put(`/api/lock/review/request/${testBrew.shareId}`)
+ .catch((err)=>{return err;});
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ message : `Cannot find a locked brew with ID ${testBrew.shareId}`,
+ name : 'Brew Not Found',
+ HBErrorCode : '70',
+ code : 500,
+ originalUrl : `/api/lock/review/request/${testBrew.shareId}`
+ });
+ });
+
+ it('Error when review is already requested', async ()=>{
+ const testLock = {
+ applied : 'YES',
+ code : 999,
+ editMessage : 'edit',
+ shareMessage : 'share',
+ reviewRequested : 'YES'
+ };
+
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.resolve(); },
+ lock : testLock
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(false);
+ });
+
+
+ const response = await app
+ .put(`/api/lock/review/request/${testBrew.shareId}`)
+ .catch((err)=>{return err;});
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '70',
+ code : 500,
+ message : `Cannot find a locked brew with ID ${testBrew.shareId}`,
+ name : 'Brew Not Found',
+ originalUrl : `/api/lock/review/request/${testBrew.shareId}`
+ });
+ });
+
+ it('Handle error while adding review request to a locked brew', async ()=>{
+ const testLock = {
+ applied : 'YES',
+ code : 999,
+ editMessage : 'edit',
+ shareMessage : 'share'
+ };
+
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.reject(); },
+ lock : testLock
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .put(`/api/lock/review/request/${testBrew.shareId}`);
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '69',
+ code : 500,
+ message : `Unable to set request for review on brew ID ${testBrew.shareId}`,
+ name : 'Can Not Set Review Request',
+ originalUrl : `/api/lock/review/request/${testBrew.shareId}`
+ });
+ });
+
+ it('Clear review request from a locked brew', async ()=>{
+ const testLock = {
+ applied : 'YES',
+ code : 999,
+ editMessage : 'edit',
+ shareMessage : 'share',
+ reviewRequested : 'YES'
+ };
+
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.resolve(); },
+ lock : testLock
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .put(`/api/lock/review/remove/${testBrew.shareId}`);
+
+ expect(response.status).toBe(200);
+ expect(response.body).toEqual({
+ message : `Review request removed for brew ID ${testBrew.shareId} - ${testBrew.title}`,
+ name : 'Review Request Cleared'
+ });
+ });
+
+ it('Error when clearing review request from a brew with no review request', async ()=>{
+ const testBrew = {
+ shareId : 'shareId',
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(false);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .put(`/api/lock/review/remove/${testBrew.shareId}`);
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '73',
+ message : `Brew ID ${testBrew.shareId} does not have a review pending!`,
+ name : 'Can Not Clear Review Request',
+ originalUrl : `/api/lock/review/remove/${testBrew.shareId}`
+ });
+ });
+
+ it('Handle error while clearing review request from a locked brew', async ()=>{
+ const testLock = {
+ applied : 'YES',
+ code : 999,
+ editMessage : 'edit',
+ shareMessage : 'share',
+ reviewRequested : 'YES'
+ };
+
+ const testBrew = {
+ shareId : 'shareId',
+ title : 'title',
+ markModified : ()=>{ return true; },
+ save : ()=>{ return Promise.reject(); },
+ lock : testLock
+ };
+
+ jest.spyOn(HomebrewModel, 'findOne')
+ .mockImplementationOnce(()=>{
+ return Promise.resolve(testBrew);
+ });
+
+ const response = await app
+ .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
+ .put(`/api/lock/review/remove/${testBrew.shareId}`);
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({
+ HBErrorCode : '72',
+ message : `Unable to remove request for review on brew ID ${testBrew.shareId}`,
+ name : 'Can Not Clear Review Request',
+ originalUrl : `/api/lock/review/remove/${testBrew.shareId}`
+ });
+ });
+ });
+ });
});
diff --git a/server/app.js b/server/app.js
index 76caf6fed..b7d990baf 100644
--- a/server/app.js
+++ b/server/app.js
@@ -2,7 +2,7 @@
// Set working directory to project root
import { dirname } from 'path';
import { fileURLToPath } from 'url';
-import packageJSON from './../package.json' with { type: 'json' };
+import packageJSON from './../package.json' with { type: 'json' };
const __dirname = dirname(fileURLToPath(import.meta.url));
process.chdir(`${__dirname}/..`);
@@ -11,7 +11,6 @@ const version = packageJSON.version;
import _ from 'lodash';
import jwt from 'jwt-simple';
import express from 'express';
-import yaml from 'js-yaml';
import config from './config.js';
import fs from 'fs-extra';
@@ -70,13 +69,11 @@ const corsOptions = {
'https://homebrewery-stage.herokuapp.com',
];
- if(isLocalEnvironment) {
- allowedOrigins.push('http://localhost:8000', 'http://localhost:8010');
- }
+ 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)) {
+ if(!origin || allowedOrigins.includes(origin) || herokuRegex.test(origin) || (isLocalEnvironment && localNetworkRegex.test(origin))) {
callback(null, true);
} else {
console.log(origin, 'not allowed');
@@ -352,7 +349,7 @@ app.get('/user/:username', async (req, res, next)=>{
app.put('/api/user/rename', 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)
diff --git a/server/googleActions.js b/server/googleActions.js
index 2c2cbac73..0ca7556ba 100644
--- a/server/googleActions.js
+++ b/server/googleActions.js
@@ -27,12 +27,12 @@ if(!config.get('service_account')){
const defaultAuth = serviceAuth || config.get('google_api_key');
const retryConfig = {
- retry: 3, // Number of retry attempts
- retryDelay: 100, // Initial delay in milliseconds
- retryDelayMultiplier: 2, // Multiplier for exponential backoff
- maxRetryDelay: 32000, // Maximum delay in milliseconds
- httpMethodsToRetry: ['PATCH'], // Only retry PATCH requests
- statusCodesToRetry: [[429, 429]], // Only retry on 429 status code
+ retry : 3, // Number of retry attempts
+ retryDelay : 100, // Initial delay in milliseconds
+ retryDelayMultiplier : 2, // Multiplier for exponential backoff
+ maxRetryDelay : 32000, // Maximum delay in milliseconds
+ httpMethodsToRetry : ['PATCH'], // Only retry PATCH requests
+ statusCodesToRetry : [[429, 429]], // Only retry on 429 status code
};
const GoogleActions = {
@@ -177,8 +177,8 @@ const GoogleActions = {
mimeType : 'text/plain',
body : brew.text
},
- headers: {
- 'X-Forwarded-For': userIp, // Set the X-Forwarded-For header
+ headers : {
+ 'X-Forwarded-For' : userIp, // Set the X-Forwarded-For header
},
retryConfig
})
diff --git a/server/homebrew.api.js b/server/homebrew.api.js
index 7bd88cbdb..2ab29f31b 100644
--- a/server/homebrew.api.js
+++ b/server/homebrew.api.js
@@ -8,9 +8,11 @@ import Markdown from '../shared/naturalcrit/markdown.js';
import yaml from 'js-yaml';
import asyncHandler from 'express-async-handler';
import { nanoid } from 'nanoid';
-import { splitTextStyleAndMetadata } from '../shared/helpers.js';
+import { splitTextStyleAndMetadata,
+ brewSnippetsToJSON } from '../shared/helpers.js';
import checkClientVersion from './middleware/check-client-version.js';
+
const router = express.Router();
import { DEFAULT_BREW, DEFAULT_BREW_LOAD } from './brewDefaults.js';
@@ -92,7 +94,7 @@ const api = {
const accessMap = {
edit : { editId: id },
share : { shareId: id },
- admin : { $or : [{ editId: id }, { shareId: id }] }
+ admin : { $or: [{ editId: id }, { shareId: id }] }
};
// Try to find the document in the Homebrewery database -- if it doesn't exist, that's fine.
@@ -118,8 +120,8 @@ const api = {
throw { ...accessError, message: 'User is not logged in', HBErrorCode: '04' };
}
- if(stub?.lock?.locked && accessType != 'edit') {
- throw { HBErrorCode: '51', code: stub?.lock.code, message: stub?.lock.shareMessage, brewId: stub?.shareId, brewTitle: stub?.title };
+ if(stub?.lock && accessType === 'share') {
+ throw { HBErrorCode: '51', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title, brewAuthors: stub.authors };
}
// If there's a google id, get it if requesting the full brew or if no stub found yet
@@ -175,12 +177,15 @@ const api = {
`${text}`;
}
const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']);
+ const snippetsArray = brewSnippetsToJSON('brew_snippets', brew.snippets, null, false).snippets;
+ metadata.snippets = snippetsArray.length > 0 ? snippetsArray : undefined;
text = `\`\`\`metadata\n` +
`${yaml.dump(metadata)}\n` +
`\`\`\`\n\n` +
`${text}`;
return text;
},
+
getGoodBrewTitle : (text)=>{
const tokens = Markdown.marked.lexer(text);
return (tokens.find((token)=>token.type === 'heading' || token.type === 'paragraph')?.text || 'No Title')
@@ -294,13 +299,13 @@ const api = {
currentTheme = req.brew;
splitTextStyleAndMetadata(currentTheme);
- if(!currentTheme.tags.some(tag => tag === "meta:theme" || tag === "meta:Theme"))
+ if(!currentTheme.tags.some((tag)=>tag === 'meta:theme' || tag === 'meta:Theme'))
throw { brewId: req.params.id, name: 'Invalid Theme Selected', message: 'Selected theme does not have the meta:theme tag', status: 422, HBErrorCode: '10' };
themeName ??= currentTheme.title;
themeAuthor ??= currentTheme.authors?.[0];
// If there is anything in the snippets or style members, append them to the appropriate array
- if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets));
+ if(currentTheme?.snippets) completeSnippets.push({ name: currentTheme.title, snippets: currentTheme.snippets });
if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`);
req.params.id = currentTheme.theme;
diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js
index 1c42cb4be..8bb3a0c0b 100644
--- a/server/homebrew.api.spec.js
+++ b/server/homebrew.api.spec.js
@@ -302,7 +302,7 @@ describe('Tests for api', ()=>{
});
it('access is denied to a locked brew', async()=>{
- const lockBrew = { title: 'test brew', shareId: '1', lock: { locked: true, code: 404, shareMessage: 'brew locked' } };
+ const lockBrew = { title: 'test brew', shareId: '1', lock: { code: 404, shareMessage: 'brew locked' } };
model.get = jest.fn(()=>toBrewPromise(lockBrew));
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
@@ -939,7 +939,7 @@ brew`);
});
describe('Get CSS', ()=>{
it('should return brew style content as CSS text', async ()=>{
- const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n````\n\n' };
+ const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n```\n\n' };
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
@@ -1034,7 +1034,7 @@ brew`);
expect(testBrew.theme).toEqual('5ePHB');
expect(testBrew.lang).toEqual('en');
// Style
- expect(testBrew.style).toEqual('style\nstyle\nstyle');
+ expect(testBrew.style).toEqual('style\nstyle\nstyle\n');
// Text
expect(testBrew.text).toEqual('text\n');
});
diff --git a/server/homebrew.model.js b/server/homebrew.model.js
index adeac0d5d..2e74b1de2 100644
--- a/server/homebrew.model.js
+++ b/server/homebrew.model.js
@@ -27,7 +27,9 @@ const HomebrewSchema = mongoose.Schema({
updatedAt : { type: Date, default: Date.now },
lastViewed : { type: Date, default: Date.now },
views : { type: Number, default: 0 },
- version : { type: Number, default: 1 }
+ version : { type: Number, default: 1 },
+
+ lock : { type: Object }
}, { versionKey: false });
HomebrewSchema.statics.increaseView = async function(query) {
@@ -63,7 +65,7 @@ HomebrewSchema.statics.getByUser = async function(username, allowAccess=false, f
const Homebrew = mongoose.model('Homebrew', HomebrewSchema);
-export {
+export {
HomebrewSchema as schema,
Homebrew as model
};
diff --git a/server/vault.api.js b/server/vault.api.js
index 6a7b9fb91..3a6c6e989 100644
--- a/server/vault.api.js
+++ b/server/vault.api.js
@@ -1,6 +1,6 @@
import express from 'express';
import asyncHandler from 'express-async-handler';
-import {model as HomebrewModel } from './homebrew.model.js';
+import { model as HomebrewModel } from './homebrew.model.js';
const router = express.Router();
@@ -29,7 +29,7 @@ const rendererConditions = (legacy, v3)=>{
return {}; // If all renderers selected, renderer field not needed in query for speed
};
-const sortConditions = (sort, dir) => {
+const sortConditions = (sort, dir)=>{
return { [sort]: dir === 'asc' ? 1 : -1 };
};
diff --git a/shared/helpers.js b/shared/helpers.js
index 2ad9218fa..0ca681dfb 100644
--- a/shared/helpers.js
+++ b/shared/helpers.js
@@ -2,24 +2,103 @@ import _ from 'lodash';
import yaml from 'js-yaml';
import request from '../client/homebrew/utils/request-middleware.js';
+// Convert the templates from a brew to a Snippets Structure.
+const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=null, full=true)=>{
+ const textSplit = /^(\\snippet +.+\n)/gm;
+ const mpAsSnippets = [];
+ // Snippets from Themes first.
+ if(themeBundleSnippets) {
+ for (let themes of themeBundleSnippets) {
+ if(typeof themes !== 'string') {
+ const userSnippets = [];
+ const snipSplit = themes.snippets.trim().split(textSplit).slice(1);
+ for (let snips = 0; snips < snipSplit.length; snips+=2) {
+ if(!snipSplit[snips].startsWith('\\snippet ')) break;
+ const snippetName = snipSplit[snips].split(/\\snippet +/)[1].split('\n')[0].trim();
+ if(snippetName.length != 0) {
+ userSnippets.push({
+ name : snippetName,
+ icon : '',
+ gen : snipSplit[snips + 1],
+ });
+ }
+ }
+ if(userSnippets.length > 0) {
+ mpAsSnippets.push({
+ name : themes.name,
+ icon : '',
+ gen : '',
+ subsnippets : userSnippets
+ });
+ }
+ }
+ }
+ }
+ // Local Snippets
+ if(userBrewSnippets) {
+ const userSnippets = [];
+ const snipSplit = userBrewSnippets.trim().split(textSplit).slice(1);
+ for (let snips = 0; snips < snipSplit.length; snips+=2) {
+ if(!snipSplit[snips].startsWith('\\snippet ')) break;
+ const snippetName = snipSplit[snips].split(/\\snippet +/)[1].split('\n')[0].trim();
+ if(snippetName.length != 0) {
+ const subSnip = {
+ name : snippetName,
+ gen : snipSplit[snips + 1],
+ };
+ // if(full) subSnip.icon = '';
+ userSnippets.push(subSnip);
+ }
+ }
+ if(userSnippets.length) {
+ mpAsSnippets.push({
+ name : menuTitle,
+ // icon : '',
+ subsnippets : userSnippets
+ });
+ }
+ }
+
+ const returnObj = {
+ snippets : mpAsSnippets
+ };
+
+ if(full) {
+ returnObj.groupName = 'Brew Snippets';
+ returnObj.icon = 'fas fa-th-list';
+ returnObj.view = 'text';
+ }
+
+ return returnObj;
+};
+
+const yamlSnippetsToText = (yamlObj)=>{
+ if(typeof yamlObj == 'string') return yamlObj;
+
+ let snippetsText = '';
+
+ for (let snippet of yamlObj) {
+ for (let subSnippet of snippet.subsnippets) {
+ snippetsText = `${snippetsText}\\snippet ${subSnippet.name}\n${subSnippet.gen || ''}\n`;
+ }
+ }
+ return snippetsText;
+};
+
const splitTextStyleAndMetadata = (brew)=>{
brew.text = brew.text.replaceAll('\r\n', '\n');
if(brew.text.startsWith('```metadata')) {
- const index = brew.text.indexOf('```\n\n');
- const metadataSection = brew.text.slice(12, index - 1);
+ const index = brew.text.indexOf('\n```\n\n');
+ const metadataSection = brew.text.slice(11, index + 1);
const metadata = yaml.load(metadataSection);
Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang']));
- brew.text = brew.text.slice(index + 5);
+ brew.snippets = yamlSnippetsToText(_.pick(metadata, ['snippets']).snippets || '');
+ brew.text = brew.text.slice(index + 6);
}
if(brew.text.startsWith('```css')) {
- const index = brew.text.indexOf('```\n\n');
- brew.style = brew.text.slice(7, index - 1);
- brew.text = brew.text.slice(index + 5);
- }
- if(brew.text.startsWith('```snippets')) {
- const index = brew.text.indexOf('```\n\n');
- brew.snippets = brew.text.slice(11, index - 1);
- brew.text = brew.text.slice(index + 5);
+ const index = brew.text.indexOf('\n```\n\n');
+ brew.style = brew.text.slice(7, index + 1);
+ brew.text = brew.text.slice(index + 6);
}
// Handle old brews that still have empty strings in the tags metadata
@@ -64,4 +143,5 @@ export {
splitTextStyleAndMetadata,
printCurrentBrew,
fetchThemeBundle,
+ brewSnippetsToJSON
};
diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js
index 3160b1b8d..f8b9a49c6 100644
--- a/shared/naturalcrit/markdown.js
+++ b/shared/naturalcrit/markdown.js
@@ -4,11 +4,16 @@ import _ from 'lodash';
import { Parser as MathParser } from 'expr-eval';
import { marked as Marked } from 'marked';
import MarkedExtendedTables from 'marked-extended-tables';
+import MarkedDefinitionLists from 'marked-definition-lists';
+import MarkedAlignedParagraphs from 'marked-alignment-paragraphs';
+import MarkedNonbreakingSpaces from 'marked-nonbreaking-spaces';
+import MarkedSubSuperText from 'marked-subsuper-text';
import { markedSmartypantsLite as MarkedSmartypantsLite } from 'marked-smartypants-lite';
import { gfmHeadingId as MarkedGFMHeadingId, resetHeadings as MarkedGFMResetHeadingIDs } from 'marked-gfm-heading-id';
import { markedEmoji as MarkedEmojis } from 'marked-emoji';
-import MarkedDefinitionLists from 'marked-definition-lists';
-import MarkedSubSuperText from 'marked-subsuper-text';
+
+import { romanize } from 'romans';
+import writtenNumber from 'written-number';
//Icon fonts included so they can appear in emoji autosuggest dropdown
import diceFont from '../../themes/fonts/iconFonts/diceFont.js';
@@ -60,9 +65,57 @@ mathParser.functions.signed = function (a) {
if(a >= 0) return `+${a}`;
return `${a}`;
};
+// Add Roman numeral functions
+mathParser.functions.toRomans = function (a) {
+ return romanize(a);
+};
+mathParser.functions.toRomansUpper = function (a) {
+ return romanize(a).toUpperCase();
+};
+mathParser.functions.toRomansLower = function (a) {
+ return romanize(a).toLowerCase();
+};
+// Add character functions
+mathParser.functions.toChar = function (a) {
+ if(a <= 0) return a;
+ const genChars = function (i) {
+ return (i > 26 ? genChars(Math.floor((i - 1) / 26)) : '') + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[(i - 1) % 26];
+ };
+ return genChars(a);
+};
+mathParser.functions.toCharUpper = function (a) {
+ return mathParser.functions.toChar(a).toUpperCase();
+};
+mathParser.functions.toCharLower = function (a) {
+ return mathParser.functions.toChar(a).toLowerCase();
+};
+// Add word functions
+mathParser.functions.toWords = function (a) {
+ return writtenNumber(a);
+};
+mathParser.functions.toWordsUpper = function (a) {
+ return mathParser.functions.toWords(a).toUpperCase();
+};
+mathParser.functions.toWordsLower = function (a) {
+ return mathParser.functions.toWords(a).toLowerCase();
+};
+mathParser.functions.toWordsCaps = function (a) {
+ const words = mathParser.functions.toWords(a).split(' ');
+ return words.map((word)=>{
+ return word.replace(/(?:^|\b|\s)(\w)/g, function(w, index) {
+ return index === 0 ? w.toLowerCase() : w.toUpperCase();
+ });
+ }).join(' ');
+};
+
+// Normalize variable names; trim edge spaces and shorten blocks of whitespace to 1 space
+const normalizeVarNames = (label)=>{
+ return label.trim().replace(/\s+/g, ' ');
+};
//Processes the markdown within an HTML block if it's just a class-wrapper
-renderer.html = function (html) {
+renderer.html = function (token) {
+ let html = token.text;
if(_.startsWith(_.trim(html), '')){
const openTag = html.substring(0, html.indexOf('>')+1);
html = html.substring(html.indexOf('>')+1);
@@ -73,18 +126,21 @@ renderer.html = function (html) {
};
// Don't wrap {{ Spans alone on a line, or {{ Divs in
tags
-renderer.paragraph = function(text){
+renderer.paragraph = function(token){
let match;
+ const text = this.parser.parseInline(token.tokens);
if(text.startsWith('
)$/))
return `${match[1].trim() ? `
${match[1]}
` : ''}
${this.parser.parseInline(token.tokens)}`;
- }
-
-};
-
-
const forcedParagraphBreaks = {
name : 'hardBreaks',
level : 'block',
@@ -388,28 +408,7 @@ const forcedParagraphBreaks = {
}
},
renderer(token) {
- return ` \n`.repeat(token.length);
- }
-};
-
-const nonbreakingSpaces = {
- name : 'nonbreakingSpaces',
- level : 'inline',
- start(src) { return src.match(/:>+/m)?.index; }, // Hint to Marked.js to stop and check for a match
- tokenizer(src, tokens) {
- const regex = /:(>+)/ym;
- const match = regex.exec(src);
- if(match?.length) {
- return {
- type : 'nonbreakingSpaces', // Should match "name" above
- raw : match[0], // Text to consume from the source
- length : match[1].length,
- text : ''
- };
- }
- },
- renderer(token) {
- return ` `.repeat(token.length).concat('');
+ return `
\n`.repeat(token.length);
}
};
@@ -419,7 +418,7 @@ const replaceVar = function(input, hoist=false, allowUnresolved=false) {
const match = regex.exec(input);
const prefix = match[1];
- const label = match[2];
+ const label = normalizeVarNames(match[2]); // Ensure the label name is normalized as it should be in the var stack.
//v=====--------------------< HANDLE MATH >-------------------=====v//
const mathRegex = /[a-z]+\(|[+\-*/^(),]/g;
@@ -574,8 +573,8 @@ function MarkedVariables() {
});
}
if(match[3]) { // Block Definition
- const label = match[4] ? match[4].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
- const content = match[5] ? match[5].trim().replace(/[ \t]+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
+ const label = match[4] ? normalizeVarNames(match[4]) : null;
+ const content = match[5] ? match[5].trim().replace(/[ \t]+/g, ' ') : null; // Normalize text content (except newlines for block-level content)
varsQueue.push(
{ type : 'varDefBlock',
@@ -584,7 +583,7 @@ function MarkedVariables() {
});
}
if(match[6]) { // Block Call
- const label = match[7] ? match[7].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
+ const label = match[7] ? normalizeVarNames(match[7]) : null;
varsQueue.push(
{ type : 'varCallBlock',
@@ -593,7 +592,7 @@ function MarkedVariables() {
});
}
if(match[8]) { // Inline Definition
- const label = match[10] ? match[10].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
+ const label = match[10] ? normalizeVarNames(match[10]) : null;
let content = match[11] || null;
// In case of nested (), find the correct matching end )
@@ -625,7 +624,7 @@ function MarkedVariables() {
});
}
if(match[12]) { // Inline Call
- const label = match[13] ? match[13].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space
+ const label = match[13] ? normalizeVarNames(match[13]) : null;
varsQueue.push(
{ type : 'varCallInline',
@@ -682,12 +681,13 @@ const tableTerminators = [
Marked.use(MarkedVariables());
Marked.use(MarkedDefinitionLists());
-Marked.use({ extensions : [justifiedParagraphs, forcedParagraphBreaks,
- nonbreakingSpaces, mustacheSpans, mustacheDivs, mustacheInjectInline] });
+Marked.use({ extensions : [forcedParagraphBreaks, mustacheSpans, mustacheDivs, mustacheInjectInline] });
Marked.use(mustacheInjectBlock);
+Marked.use(MarkedAlignedParagraphs());
Marked.use(MarkedSubSuperText());
+Marked.use(MarkedNonbreakingSpaces());
Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false });
-Marked.use(MarkedExtendedTables({interruptPatterns : tableTerminators}), MarkedGFMHeadingId({ globalSlugs: true }),
+Marked.use(MarkedExtendedTables({ interruptPatterns: tableTerminators }), MarkedGFMHeadingId({ globalSlugs: true }),
MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions));
function cleanUrl(href) {
@@ -752,12 +752,12 @@ const processStyleTags = (string)=>{
obj[key.trim()] = value.trim();
return obj;
}, {}) || null;
- const styles = tags?.length ? tags.reduce((styleObj, style) => {
- const index = style.indexOf(':');
- const [key, value] = [style.substring(0, index), style.substring(index + 1)];
- styleObj[key.trim()] = value.replace(/"?([^"]*)"?/g, '$1').trim();
- return styleObj;
- }, {}) : null;
+ const styles = tags?.length ? tags.reduce((styleObj, style)=>{
+ const index = style.indexOf(':');
+ const [key, value] = [style.substring(0, index), style.substring(index + 1)];
+ styleObj[key.trim()] = value.replace(/"?([^"]*)"?/g, '$1').trim();
+ return styleObj;
+ }, {}) : null;
return {
id : id,
@@ -773,8 +773,8 @@ const extractHTMLStyleTags = (htmlString)=>{
const id = firstElementOnly.match(/id="([^"]*)"/)?.[1] || null;
const classes = firstElementOnly.match(/class="([^"]*)"/)?.[1] || null;
const styles = firstElementOnly.match(/style="([^"]*)"/)?.[1]
- ?.split(';').reduce((styleObj, style) => {
- if (style.trim() === '') return styleObj;
+ ?.split(';').reduce((styleObj, style)=>{
+ if(style.trim() === '') return styleObj;
const index = style.indexOf(':');
const [key, value] = [style.substring(0, index), style.substring(index + 1)];
styleObj[key.trim()] = value.trim();
@@ -784,7 +784,7 @@ const extractHTMLStyleTags = (htmlString)=>{
?.filter((attr)=>!attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="'))
.reduce((obj, attr)=>{
const index = attr.indexOf('=');
- let [key, value] = [attr.substring(0, index), attr.substring(index + 1)];
+ const [key, value] = [attr.substring(0, index), attr.substring(index + 1)];
obj[key.trim()] = value.replace(/"/g, '');
return obj;
}, {}) || null;
@@ -797,7 +797,7 @@ const extractHTMLStyleTags = (htmlString)=>{
};
};
-const mergeHTMLTags = (originalTags, newTags) => {
+const mergeHTMLTags = (originalTags, newTags)=>{
return {
id : newTags.id || originalTags.id || null,
classes : [originalTags.classes, newTags.classes].join(' ').trim() || null,
@@ -813,7 +813,13 @@ let globalPageNumber = 0;
const Markdown = {
marked : Marked,
render : (rawBrewText, pageNumber=0)=>{
- globalVarsList[pageNumber] = {}; //Reset global links for current page, to ensure values are parsed in order
+ const lastPageNumber = pageNumber > 0 ? globalVarsList[pageNumber - 1].HB_pageNumber.content : 0;
+ globalVarsList[pageNumber] = { //Reset global links for current page, to ensure values are parsed in order
+ 'HB_pageNumber' : { //Add document variables for this page
+ content : !isNaN(Number(lastPageNumber)) ? Number(lastPageNumber) + 1 : lastPageNumber,
+ resolved : true
+ }
+ };
varsQueue = []; //Could move into MarkedVariables()
globalPageNumber = pageNumber;
if(pageNumber==0) {
diff --git a/shared/naturalcrit/nav/nav.jsx b/shared/naturalcrit/nav/nav.jsx
index d9b403239..50dff4c33 100644
--- a/shared/naturalcrit/nav/nav.jsx
+++ b/shared/naturalcrit/nav/nav.jsx
@@ -12,8 +12,8 @@ const Nav = {
displayName : 'Nav.base',
render : function(){
return
- {this.props.children}
- ;
+ {this.props.children}
+ ;
}
}),
logo : function(){
diff --git a/shared/naturalcrit/splitPane/splitPane.jsx b/shared/naturalcrit/splitPane/splitPane.jsx
index 1500c759f..4c77d81a5 100644
--- a/shared/naturalcrit/splitPane/splitPane.jsx
+++ b/shared/naturalcrit/splitPane/splitPane.jsx
@@ -29,8 +29,8 @@ const SplitPane = (props)=>{
const limitPosition = (x, min = 1, max = window.innerWidth - 13)=>Math.round(Math.min(max, Math.max(min, x)));
//when resizing, the divider should grow smaller if less space is given, then grow back if the space is restored, to the original position
- const handleResize = () =>setDividerPos(limitPosition(window.localStorage.getItem(storageKey), 0.1 * (window.innerWidth - 13), 0.9 * (window.innerWidth - 13)));
-
+ const handleResize = ()=>setDividerPos(limitPosition(window.localStorage.getItem(storageKey), 0.1 * (window.innerWidth - 13), 0.9 * (window.innerWidth - 13)));
+
const handleUp =(e)=>{
e.preventDefault();
if(isDragging) {
diff --git a/shared/naturalcrit/splitPane/splitPane.less b/shared/naturalcrit/splitPane/splitPane.less
index 8b61097be..80a8695af 100644
--- a/shared/naturalcrit/splitPane/splitPane.less
+++ b/shared/naturalcrit/splitPane/splitPane.less
@@ -21,8 +21,8 @@
background-color : #BBBBBB;
.dots {
display : table-cell;
- text-align : center;
vertical-align : middle;
+ text-align : center;
i {
display : block !important;
margin : 10px 0px;
diff --git a/shared/naturalcrit/styles/animations.less b/shared/naturalcrit/styles/animations.less
index 69aac3e09..5757df151 100644
--- a/shared/naturalcrit/styles/animations.less
+++ b/shared/naturalcrit/styles/animations.less
@@ -3,127 +3,127 @@
@defaultEasing : ease;
//Animates all properties on an element
-.animateAll(@duration : @defaultDuration, @easing : @defaultEasing){
- -webkit-transition: all @duration @easing;
- -moz-transition: all @duration @easing;
- -o-transition: all @duration @easing;
- transition: all @duration @easing;
+.animateAll(@duration : @defaultDuration, @easing : @defaultEasing) {
+ -webkit-transition : all @duration @easing;
+ -moz-transition : all @duration @easing;
+ -o-transition : all @duration @easing;
+ transition : all @duration @easing;
}
//Animates Specific property
-.animate(@prop, @duration : @defaultDuration, @easing : @defaultEasing){
- -webkit-transition: @prop @duration @easing;
- -moz-transition: @prop @duration @easing;
- -o-transition: @prop @duration @easing;
- transition: @prop @duration @easing;
+.animate(@prop, @duration : @defaultDuration, @easing : @defaultEasing) {
+ -webkit-transition : @prop @duration @easing;
+ -moz-transition : @prop @duration @easing;
+ -o-transition : @prop @duration @easing;
+ transition : @prop @duration @easing;
}
-.animateMany(...){
+.animateMany(...) {
@value: ~`"@{arguments}".replace(/[\[\]]|\,\sX/g, '')`;
- -webkit-transition-property: @value;
- -moz-transition-property: @value;
- -o-transition-property: @value;
- transition-property: @value;
+ -webkit-transition-property : @value;
+ -moz-transition-property : @value;
+ -o-transition-property : @value;
+ transition-property : @value;
.animateDuration();
.animateEasing();
}
-.animateDuration(@duration : @defaultDuration){
- -webkit-transition-duration: @duration;
- -moz-transition-duration: @duration;
- -o-transition-duration: @duration;
- transition-duration: @duration;
+.animateDuration(@duration : @defaultDuration) {
+ -webkit-transition-duration : @duration;
+ -moz-transition-duration : @duration;
+ -o-transition-duration : @duration;
+ transition-duration : @duration;
}
-.animateEasing(@easing : @defaultEasing){
- -webkit-transition-timing-function: @easing;
- -moz-transition-timing-function: @easing;
- -o-transition-timing-function: @easing;
- transition-timing-function: @easing;
+.animateEasing(@easing : @defaultEasing) {
+ -webkit-transition-timing-function : @easing;
+ -moz-transition-timing-function : @easing;
+ -o-transition-timing-function : @easing;
+ transition-timing-function : @easing;
}
.transition (@prop, @duration: @defaultDuration) {
- -webkit-transition: @prop @duration, -webkit-transform @duration;
- -moz-transition: @prop @duration, -moz-transform @duration;
- -o-transition: @prop @duration, -o-transform @duration;
- -ms-transition: @prop @duration, -ms-transform @duration;
- transition: @prop @duration, transform @duration;
+ -webkit-transition : @prop @duration, -webkit-transform @duration;
+ -moz-transition : @prop @duration, -moz-transform @duration;
+ -o-transition : @prop @duration, -o-transform @duration;
+ -ms-transition : @prop @duration, -ms-transform @duration;
+ transition : @prop @duration, transform @duration;
}
.transform (@transform) {
- -webkit-transform: @transform;
- -moz-transform: @transform;
- -o-transform: @transform;
- -ms-transform: @transform;
- transform: @transform;
+ -webkit-transform : @transform;
+ -moz-transform : @transform;
+ -o-transform : @transform;
+ -ms-transform : @transform;
+ transform : @transform;
}
-.delay(@delay){
- animation-delay:@delay;
- -webkit-animation-delay:@delay;
- transition-delay:@delay;
- -webkit-transition-delay:@delay;
+.delay(@delay) {
+ -webkit-transition-delay : @delay;
+ transition-delay : @delay;
+ -webkit-animation-delay : @delay;
+ animation-delay : @delay;
}
-.keep(){
- -webkit-animation-fill-mode:forwards;
- -moz-animation-fill-mode:forwards;
- -ms-animation-fill-mode:forwards;
- -o-animation-fill-mode:forwards;
- animation-fill-mode:forwards;
+.keep() {
+ -webkit-animation-fill-mode : forwards;
+ -moz-animation-fill-mode : forwards;
+ -ms-animation-fill-mode : forwards;
+ -o-animation-fill-mode : forwards;
+ animation-fill-mode : forwards;
}
-.sequentialDelay(@delayInc : 0.2s, @initialDelay : 0s){
- &:nth-child(1){.delay(0*@delayInc + @initialDelay)}
- &:nth-child(2){.delay(1*@delayInc + @initialDelay)}
- &:nth-child(3){.delay(2*@delayInc + @initialDelay)}
- &:nth-child(4){.delay(3*@delayInc + @initialDelay)}
- &:nth-child(5){.delay(4*@delayInc + @initialDelay)}
- &:nth-child(6){.delay(5*@delayInc + @initialDelay)}
- &:nth-child(7){.delay(6*@delayInc + @initialDelay)}
- &:nth-child(8){.delay(7*@delayInc + @initialDelay)}
- &:nth-child(9){.delay(8*@delayInc + @initialDelay)}
- &:nth-child(10){.delay(9*@delayInc + @initialDelay)}
- &:nth-child(11){.delay(10*@delayInc + @initialDelay)}
- &:nth-child(12){.delay(11*@delayInc + @initialDelay)}
- &:nth-child(13){.delay(12*@delayInc + @initialDelay)}
- &:nth-child(14){.delay(13*@delayInc + @initialDelay)}
- &:nth-child(15){.delay(14*@delayInc + @initialDelay)}
- &:nth-child(16){.delay(15*@delayInc + @initialDelay)}
- &:nth-child(17){.delay(16*@delayInc + @initialDelay)}
- &:nth-child(18){.delay(17*@delayInc + @initialDelay)}
- &:nth-child(19){.delay(18*@delayInc + @initialDelay)}
- &:nth-child(20){.delay(19*@delayInc + @initialDelay)}
+.sequentialDelay(@delayInc : 0.2s, @initialDelay : 0s) {
+ &:nth-child(1) {.delay(0*@delayInc + @initialDelay); }
+ &:nth-child(2) {.delay(1*@delayInc + @initialDelay); }
+ &:nth-child(3) {.delay(2*@delayInc + @initialDelay); }
+ &:nth-child(4) {.delay(3*@delayInc + @initialDelay); }
+ &:nth-child(5) {.delay(4*@delayInc + @initialDelay); }
+ &:nth-child(6) {.delay(5*@delayInc + @initialDelay); }
+ &:nth-child(7) {.delay(6*@delayInc + @initialDelay); }
+ &:nth-child(8) {.delay(7*@delayInc + @initialDelay); }
+ &:nth-child(9) {.delay(8*@delayInc + @initialDelay); }
+ &:nth-child(10) {.delay(9*@delayInc + @initialDelay); }
+ &:nth-child(11) {.delay(10*@delayInc + @initialDelay); }
+ &:nth-child(12) {.delay(11*@delayInc + @initialDelay); }
+ &:nth-child(13) {.delay(12*@delayInc + @initialDelay); }
+ &:nth-child(14) {.delay(13*@delayInc + @initialDelay); }
+ &:nth-child(15) {.delay(14*@delayInc + @initialDelay); }
+ &:nth-child(16) {.delay(15*@delayInc + @initialDelay); }
+ &:nth-child(17) {.delay(16*@delayInc + @initialDelay); }
+ &:nth-child(18) {.delay(17*@delayInc + @initialDelay); }
+ &:nth-child(19) {.delay(18*@delayInc + @initialDelay); }
+ &:nth-child(20) {.delay(19*@delayInc + @initialDelay); }
}
-.createFrames(@name, @from, @to){
+.createFrames(@name, @from, @to) {
@frames: {
from { @from(); }
to { @to(); }
};
- @-webkit-keyframes @name {@frames();}
- @-moz-keyframes @name {@frames();}
- @-ms-keyframes @name {@frames();}
- @-o-keyframes @name {@frames();}
- @keyframes @name {@frames();}
+ @-webkit-keyframes @name {@frames();}
+ @-moz-keyframes @name {@frames();}
+ @-ms-keyframes @name {@frames();}
+ @-o-keyframes @name {@frames();}
+ @keyframes @name {@frames();}
}
-.createAnimation(@name, @duration : @defaultDuration, @easing : @defaultEasing){
- -webkit-animation-name: @name;
- -moz-animation-name: @name;
- -ms-animation-name: @name;
- animation-name: @name;
- -webkit-animation-duration: @duration;
- -moz-animation-duration: @duration;
- -ms-animation-duration: @duration;
- animation-duration: @duration;
- -webkit-animation-timing-function: @easing;
- -moz-animation-timing-function: @easing;
- -ms-animation-timing-function: @easing;
- animation-timing-function: @easing;
+.createAnimation(@name, @duration : @defaultDuration, @easing : @defaultEasing) {
+ -webkit-animation-name : @name;
+ -moz-animation-name : @name;
+ -ms-animation-name : @name;
+ animation-name : @name;
+ -webkit-animation-duration : @duration;
+ -moz-animation-duration : @duration;
+ -ms-animation-duration : @duration;
+ animation-duration : @duration;
+ -webkit-animation-timing-function : @easing;
+ -moz-animation-timing-function : @easing;
+ -ms-animation-timing-function : @easing;
+ animation-timing-function : @easing;
}
@@ -132,82 +132,82 @@
Standard Animations
****************************/
-.fadeIn(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeIn(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeIn; @duration; @easing);
.createFrames(fadeIn,
- { opacity : 0; },
+ { opacity : 0; },
{ opacity : 1; }
);
}
-.fadeInDown(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeInDown(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeInDown; @duration; @easing);
.createFrames(fadeInDown,
- { opacity : 0; .transform(translateY(20px));},
+ { opacity : 0; .transform(translateY(20px));},
{ opacity : 1; .transform(translateY(0px));}
);
}
-.fadeInTop(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeInTop(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeInTop; @duration; @easing);
.createFrames(fadeInTop,
- { opacity : 0; .transform(translateY(-20px)); },
+ { opacity : 0; .transform(translateY(-20px)); },
{ opacity : 1; .transform(translateY(0px));}
);
}
-.fadeInLeft(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeInLeft(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeInLeft; @duration; @easing);
.createFrames(fadeInLeft,
- { opacity: 0; .transform(translateX(-20px));},
+ { opacity: 0; .transform(translateX(-20px));},
{ opacity: 1; .transform(translateX(0));}
);
}
-.fadeInRight(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeInRight(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeInRight; @duration; @easing);
.createFrames(fadeInRight,
- { opacity: 0; .transform(translateX(20px));},
+ { opacity: 0; .transform(translateX(20px));},
{ opacity: 1; .transform(translateX(0));}
);
}
-.fadeOut(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeOut(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeOut; @duration; @easing);
.createFrames(fadeOut,
- { opacity : 1; },
+ { opacity : 1; },
{ opacity : 0; }
);
}
-.fadeOutDown(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeOutDown(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeOutDown; @duration; @easing);
.createFrames(fadeOutDown,
- { opacity : 1; .transform(translateY(0)); visibility: visible;},
+ { opacity : 1; .transform(translateY(0)); visibility: visible;},
{ opacity : 0; .transform(translateY(20px)); visibility: hidden;}
);
}
-.fadeOutTop(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeOutTop(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeOutTop; @duration; @easing);
.createFrames(fadeOutTop,
- { opacity : 1; .transform(translateY(0)); },
+ { opacity : 1; .transform(translateY(0)); },
{ opacity : 0; .transform(translateY(-20px)); }
);
}
-.fadeOutLeft(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeOutLeft(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeOutLeft; @duration; @easing);
.createFrames(fadeOutLeft,
- { opacity : 1; .transform(translateX(0));},
+ { opacity : 1; .transform(translateX(0));},
{ opacity : 0; .transform(translateX(-20px));}
);
}
-.fadeOutRight(@duration : @defaultDuration, @easing : @defaultEasing){
+.fadeOutRight(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(fadeOutRight; @duration; @easing);
.createFrames(fadeOutRight,
- { opacity : 1; .transform(translateX(0));},
+ { opacity : 1; .transform(translateX(0));},
{ opacity : 0; .transform(translateX(20px));}
);
}
@@ -219,50 +219,50 @@
Fun Animations
****************************/
-.spin(@duration : @defaultDuration, @easing : @defaultEasing){
+.spin(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(spin, @duration, @easing);
- .spinKeyFrames(){
+ .spinKeyFrames() {
from { .transform(rotate(0deg)); }
- to { .transform(rotate(360deg)); }
+ to { .transform(rotate(360deg)); }
}
@-webkit-keyframes spin {.spinKeyFrames();}
- @-moz-keyframes spin {.spinKeyFrames();}
- @-ms-keyframes spin {.spinKeyFrames();}
- @-o-keyframes spin {.spinKeyFrames();}
- @keyframes spin {.spinKeyFrames();}
+ @-moz-keyframes spin {.spinKeyFrames();}
+ @-ms-keyframes spin {.spinKeyFrames();}
+ @-o-keyframes spin {.spinKeyFrames();}
+ @keyframes spin {.spinKeyFrames();}
}
-.bounce(@duration : @defaultDuration, @easing : @defaultEasing){
+.bounce(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(bounce, @duration, @easing);
- .bounceKeyFrames(){
+ .bounceKeyFrames() {
0%, 20%, 50%, 80%, 100% { .transform(translateY(0));}
40% { .transform(translateY(-30px));}
60% { .transform(translateY(-15px));}
}
@-webkit-keyframes bounce {.bounceKeyFrames();}
- @-moz-keyframes bounce {.bounceKeyFrames();}
- @-ms-keyframes bounce {.bounceKeyFrames();}
- @-o-keyframes bounce {.bounceKeyFrames();}
- @keyframes bounce {.bounceKeyFrames();}
+ @-moz-keyframes bounce {.bounceKeyFrames();}
+ @-ms-keyframes bounce {.bounceKeyFrames();}
+ @-o-keyframes bounce {.bounceKeyFrames();}
+ @keyframes bounce {.bounceKeyFrames();}
}
-.pulse(@duration : @defaultDuration, @easing : @defaultEasing){
+.pulse(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(pulse, @duration, @easing);
- .pulseKeyFrames(){
- 0% { .transform(scale(1));}
- 50% { .transform(scale(1.4));}
+ .pulseKeyFrames() {
+ 0% { .transform(scale(1));}
+ 50% { .transform(scale(1.4));}
100% { .transform(scale(1));}
}
@-webkit-keyframes pulse {.pulseKeyFrames();}
- @-moz-keyframes pulse {.pulseKeyFrames();}
- @-ms-keyframes pulse {.pulseKeyFrames();}
- @-o-keyframes pulse {.pulseKeyFrames();}
- @keyframes pulse {.pulseKeyFrames();}
+ @-moz-keyframes pulse {.pulseKeyFrames();}
+ @-ms-keyframes pulse {.pulseKeyFrames();}
+ @-o-keyframes pulse {.pulseKeyFrames();}
+ @keyframes pulse {.pulseKeyFrames();}
}
-.rubberBand(@duration : @defaultDuration, @easing : @defaultEasing){
+.rubberBand(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(rubberBand, @duration, @easing);
- .rubberBandKeyFrames(){
+ .rubberBandKeyFrames() {
0% {.transform(scale(1));}
30% {.transform(scaleX(1.25) scaleY(0.75));}
40% {.transform(scaleX(0.75) scaleY(1.25));}
@@ -270,32 +270,32 @@
100% {.transform(scale(1));}
}
@-webkit-keyframes rubberBand {.rubberBandKeyFrames();}
- @-moz-keyframes rubberBand {.rubberBandKeyFrames();}
- @-ms-keyframes rubberBand {.rubberBandKeyFrames();}
- @-o-keyframes rubberBand {.rubberBandKeyFrames();}
- @keyframes rubberBand {.rubberBandKeyFrames();}
+ @-moz-keyframes rubberBand {.rubberBandKeyFrames();}
+ @-ms-keyframes rubberBand {.rubberBandKeyFrames();}
+ @-o-keyframes rubberBand {.rubberBandKeyFrames();}
+ @keyframes rubberBand {.rubberBandKeyFrames();}
}
-.shake(@duration : @defaultDuration, @easing : @defaultEasing){
+.shake(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(shake, @duration, @easing);
- .shakeKeyFrames(){
+ .shakeKeyFrames() {
0%, 100% {.transform( translateX(0));}
10%, 30%, 50%, 70%, 90% {.transform( translateX(-10px));}
20%, 40%, 60%, 80% {.transform( translateX(10px));}
}
@-webkit-keyframes shake {.shakeKeyFrames();}
- @-moz-keyframes shake {.shakeKeyFrames();}
- @-ms-keyframes shake {.shakeKeyFrames();}
- @-o-keyframes shake {.shakeKeyFrames();}
- @keyframes shake {.shakeKeyFrames();}
+ @-moz-keyframes shake {.shakeKeyFrames();}
+ @-ms-keyframes shake {.shakeKeyFrames();}
+ @-o-keyframes shake {.shakeKeyFrames();}
+ @keyframes shake {.shakeKeyFrames();}
}
-.swing(@duration : @defaultDuration, @easing : @defaultEasing){
- -webkit-transform-origin: top center;
- -ms-transform-origin: top center;
- transform-origin: top center;
+.swing(@duration : @defaultDuration, @easing : @defaultEasing) {
+ -webkit-transform-origin : top center;
+ -ms-transform-origin : top center;
+ transform-origin : top center;
.createAnimation(swing, @duration, @easing);
- .swingKeyFrames(){
+ .swingKeyFrames() {
20% {.transform(rotate(15deg));}
40% {.transform(rotate(-10deg));}
60% {.transform(rotate(5deg));}
@@ -303,18 +303,18 @@
100% {.transform(rotate(0deg));}
}
@-webkit-keyframes swing {.swingKeyFrames();}
- @-moz-keyframes swing {.swingKeyFrames();}
- @-ms-keyframes swing {.swingKeyFrames();}
- @-o-keyframes swing {.swingKeyFrames();}
- @keyframes swing {.swingKeyFrames();}
+ @-moz-keyframes swing {.swingKeyFrames();}
+ @-ms-keyframes swing {.swingKeyFrames();}
+ @-o-keyframes swing {.swingKeyFrames();}
+ @keyframes swing {.swingKeyFrames();}
}
-.twist(@duration : @defaultDuration, @easing : @defaultEasing){
- -webkit-transform-origin: center center;
- -ms-transform-origin: center center;
- transform-origin: center center;
+.twist(@duration : @defaultDuration, @easing : @defaultEasing) {
+ -webkit-transform-origin : center center;
+ -ms-transform-origin : center center;
+ transform-origin : center center;
.createAnimation(swing, @duration, @easing);
- .swingKeyFrames(){
+ .swingKeyFrames() {
20% {.transform(rotate(15deg));}
40% {.transform(rotate(-10deg));}
60% {.transform(rotate(5deg));}
@@ -322,15 +322,15 @@
100% {.transform(rotate(0deg));}
}
@-webkit-keyframes swing {.swingKeyFrames();}
- @-moz-keyframes swing {.swingKeyFrames();}
- @-ms-keyframes swing {.swingKeyFrames();}
- @-o-keyframes swing {.swingKeyFrames();}
- @keyframes swing {.swingKeyFrames();}
+ @-moz-keyframes swing {.swingKeyFrames();}
+ @-ms-keyframes swing {.swingKeyFrames();}
+ @-o-keyframes swing {.swingKeyFrames();}
+ @keyframes swing {.swingKeyFrames();}
}
-.wobble(@duration : @defaultDuration, @easing : @defaultEasing){
+.wobble(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(wobble, @duration, @easing);
- .wobbleKeyFrames(){
+ .wobbleKeyFrames() {
0% {.transform(translateX(0%));}
15% {.transform(translateX(-25%) rotate(-5deg));}
30% {.transform(translateX(20%) rotate(3deg));}
@@ -340,22 +340,22 @@
100% {.transform(translateX(0%));}
}
@-webkit-keyframes wobble {.wobbleKeyFrames();}
- @-moz-keyframes wobble {.wobbleKeyFrames();}
- @-ms-keyframes wobble {.wobbleKeyFrames();}
- @-o-keyframes wobble {.wobbleKeyFrames();}
- @keyframes wobble {.wobbleKeyFrames();}
+ @-moz-keyframes wobble {.wobbleKeyFrames();}
+ @-ms-keyframes wobble {.wobbleKeyFrames();}
+ @-o-keyframes wobble {.wobbleKeyFrames();}
+ @keyframes wobble {.wobbleKeyFrames();}
}
-.popIn(@duration : @defaultDuration, @easing : @defaultEasing){
+.popIn(@duration : @defaultDuration, @easing : @defaultEasing) {
.createAnimation(popIn, @duration, @easing);
- .popInKeyFrames(){
- 0% { .transform(scale(0));}
- 70% { .transform(scale(1.4));}
+ .popInKeyFrames() {
+ 0% { .transform(scale(0));}
+ 70% { .transform(scale(1.4));}
100% { .transform(scale(1));}
}
@-webkit-keyframes popIn {.popInKeyFrames();}
- @-moz-keyframes popIn {.popInKeyFrames();}
- @-ms-keyframes popIn {.popInKeyFrames();}
- @-o-keyframes popIn {.popInKeyFrames();}
- @keyframes popIn {.popInKeyFrames();}
+ @-moz-keyframes popIn {.popInKeyFrames();}
+ @-ms-keyframes popIn {.popInKeyFrames();}
+ @-o-keyframes popIn {.popInKeyFrames();}
+ @keyframes popIn {.popInKeyFrames();}
}
diff --git a/shared/naturalcrit/styles/colors.less b/shared/naturalcrit/styles/colors.less
index 30a7610a2..c096b9b4f 100644
--- a/shared/naturalcrit/styles/colors.less
+++ b/shared/naturalcrit/styles/colors.less
@@ -23,47 +23,47 @@
@grey : #7F8C8D;
#backgroundColors {
- &.tealLight{ background-color : @tealLight };
- &.teal{ background-color : @teal };
- &.greenLight{ background-color : @greenLight };
- &.green{ background-color : @green };
- &.blueLight{ background-color : @blueLight };
- &.blue{ background-color : @blue };
- &.purpleLight{ background-color : @purpleLight };
- &.purple{ background-color : @purple };
- &.steelLight{ background-color : @steelLight };
- &.steel{ background-color : @steel };
- &.yellowLight{ background-color : @yellowLight };
- &.yellow{ background-color : @yellow };
- &.orangeLight{ background-color : @orangeLight };
- &.orange{ background-color : @orange };
- &.redLight{ background-color : @redLight };
- &.red{ background-color : @red };
- &.silverLight{ background-color : @silverLight };
- &.silver{ background-color : @silver };
- &.greyLight{ background-color : @greyLight };
- &.grey{ background-color : @grey };
+ &.tealLight { background-color : @tealLight; };
+ &.teal { background-color : @teal; };
+ &.greenLight { background-color : @greenLight; };
+ &.green { background-color : @green; };
+ &.blueLight { background-color : @blueLight; };
+ &.blue { background-color : @blue; };
+ &.purpleLight { background-color : @purpleLight; };
+ &.purple { background-color : @purple; };
+ &.steelLight { background-color : @steelLight; };
+ &.steel { background-color : @steel; };
+ &.yellowLight { background-color : @yellowLight; };
+ &.yellow { background-color : @yellow; };
+ &.orangeLight { background-color : @orangeLight; };
+ &.orange { background-color : @orange; };
+ &.redLight { background-color : @redLight; };
+ &.red { background-color : @red; };
+ &.silverLight { background-color : @silverLight; };
+ &.silver { background-color : @silver; };
+ &.greyLight { background-color : @greyLight; };
+ &.grey { background-color : @grey; };
}
#backgroundColorsHover {
- &.tealLight:hover{ background-color : @tealLight };
- &.teal:hover{ background-color : @teal };
- &.greenLight:hover{ background-color : @greenLight };
- &.green:hover{ background-color : @green };
- &.blueLight:hover{ background-color : @blueLight };
- &.blue:hover{ background-color : @blue };
- &.purpleLight:hover{ background-color : @purpleLight };
- &.purple:hover{ background-color : @purple };
- &.steelLight:hover{ background-color : @steelLight };
- &.steel:hover{ background-color : @steel };
- &.yellowLight:hover{ background-color : @yellowLight };
- &.yellow:hover{ background-color : @yellow };
- &.orangeLight:hover{ background-color : @orangeLight };
- &.orange:hover{ background-color : @orange };
- &.redLight:hover{ background-color : @redLight };
- &.red:hover{ background-color : @red };
- &.silverLight:hover{ background-color : @silverLight };
- &.silver:hover{ background-color : @silver };
- &.greyLight:hover{ background-color : @greyLight };
- &.grey:hover{ background-color : @grey };
+ &.tealLight:hover { background-color : @tealLight; };
+ &.teal:hover { background-color : @teal; };
+ &.greenLight:hover { background-color : @greenLight; };
+ &.green:hover { background-color : @green; };
+ &.blueLight:hover { background-color : @blueLight; };
+ &.blue:hover { background-color : @blue; };
+ &.purpleLight:hover { background-color : @purpleLight; };
+ &.purple:hover { background-color : @purple; };
+ &.steelLight:hover { background-color : @steelLight; };
+ &.steel:hover { background-color : @steel; };
+ &.yellowLight:hover { background-color : @yellowLight; };
+ &.yellow:hover { background-color : @yellow; };
+ &.orangeLight:hover { background-color : @orangeLight; };
+ &.orange:hover { background-color : @orange; };
+ &.redLight:hover { background-color : @redLight; };
+ &.red:hover { background-color : @red; };
+ &.silverLight:hover { background-color : @silverLight; };
+ &.silver:hover { background-color : @silver; };
+ &.greyLight:hover { background-color : @greyLight; };
+ &.grey:hover { background-color : @grey; };
}
\ No newline at end of file
diff --git a/shared/naturalcrit/styles/core.less b/shared/naturalcrit/styles/core.less
index 3248269c5..02db5db18 100644
--- a/shared/naturalcrit/styles/core.less
+++ b/shared/naturalcrit/styles/core.less
@@ -12,37 +12,31 @@
font-family : 'CodeBold';
src : data-uri('naturalcrit/styles/CODE Bold.otf') format('opentype');
}
-html,body, #reactRoot{
+html,body, #reactRoot {
height : 100vh;
min-height : 100vh;
margin : 0;
font-family : 'Open Sans', sans-serif;
}
-*{
- box-sizing : border-box;
-}
-.colorButton(@backgroundColor : @green){
+* { box-sizing : border-box; }
+.colorButton(@backgroundColor : @green) {
.animate(background-color);
display : inline-block;
padding : 0.6em 1.2em;
- cursor : pointer;
- background-color : @backgroundColor;
font-family : 'Open Sans', sans-serif;
font-size : 0.8em;
font-weight : 800;
color : white;
- text-decoration : none;
text-transform : uppercase;
- border : none;
+ text-decoration : none;
+ cursor : pointer;
outline : none;
- &:hover{
- background-color : darken(@backgroundColor, 5%);
- }
- &:active{
- background-color : darken(@backgroundColor, 10%);
- }
- &:disabled{
+ background-color : @backgroundColor;
+ border : none;
+ &:hover { background-color : darken(@backgroundColor, 5%); }
+ &:active { background-color : darken(@backgroundColor, 10%); }
+ &:disabled {
+ cursor : not-allowed;
background-color : @silver !important;
- cursor:not-allowed;
}
}
diff --git a/shared/naturalcrit/styles/elements.less b/shared/naturalcrit/styles/elements.less
index e7f8b05f5..ca4574f26 100644
--- a/shared/naturalcrit/styles/elements.less
+++ b/shared/naturalcrit/styles/elements.less
@@ -1,86 +1,76 @@
@containerWidth : 1000px;
-html, body{
+html, body {
position : relative;
height : 100%;
min-height : 100%;
- background-color : #eee;
font-family : 'Lato', sans-serif;
color : @copyGrey;
+ background-color : #EEEEEE;
}
-.container{
+.container {
position : relative;
max-width : @containerWidth;
- margin : 0 auto;
padding-right : 20px;
padding-left : 20px;
+ margin : 0 auto;
}
-h1{
+h1 {
margin-top : 10px;
margin-bottom : 15px;
font-size : 2em;
}
-h2{
+h2 {
margin-top : 10px;
margin-bottom : 15px;
font-size : 1.5em;
font-weight : 900;
}
-h3{
+h3 {
margin-top : 5px;
margin-bottom : 7px;
font-size : 1em;
font-weight : 900;
}
-p{
+p {
margin-bottom : 1em;
font-size : 16px;
- color : @copyGrey;
line-height : 1.5em;
+ color : @copyGrey;
}
-code{
- background-color : #F8F8F8;
- font-family : 'Courier', mono;
+code {
+ font-family : 'Courier', "mono";
color : black;
white-space : pre;
+ background-color : #F8F8F8;
}
-a{
- color : inherit;
-}
-strong{
- font-weight : bold;
-}
-button{
+a { color : inherit; }
+strong { font-weight : bold; }
+button {
.button();
}
-.button(@backgroundColor : @green){
+.button(@backgroundColor : @green) {
.animate(background-color);
display : inline-block;
padding : 0.6em 1.2em;
- cursor : pointer;
- background-color : @backgroundColor;
- font-family : "Lato", Helvetica, Arial, sans-serif;
+ font-family : 'Lato', "Helvetica", "Arial", sans-serif;
font-size : 15px;
color : white;
text-decoration : none;
- border : none;
- outline : none;
- &:hover{
- background-color : darken(@backgroundColor, 5%);
- }
- &:active{
- background-color : darken(@backgroundColor, 10%);
- }
- &:disabled{
- background-color : @silver !important;
- }
-}
-.iconButton(@backgroundColor : @green){
- padding : 0.6em;
cursor : pointer;
+ outline : none;
background-color : @backgroundColor;
+ border : none;
+ &:hover { background-color : darken(@backgroundColor, 5%); }
+ &:active { background-color : darken(@backgroundColor, 10%); }
+ &:disabled { background-color : @silver !important; }
+}
+.iconButton(@backgroundColor : @green) {
+ padding : 0.6em;
font-size : 14px;
color : white;
text-align : center;
+ cursor : pointer;
+ background-color : @backgroundColor;
}
\ No newline at end of file
diff --git a/shared/naturalcrit/styles/reset.less b/shared/naturalcrit/styles/reset.less
index df5564a21..21e07a1c0 100644
--- a/shared/naturalcrit/styles/reset.less
+++ b/shared/naturalcrit/styles/reset.less
@@ -1,33 +1,23 @@
-:where(html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,button,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video){
- border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0
+:where(html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,button,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video) {padding : 0;margin : 0;font : inherit;font-size : 100%;vertical-align : baseline;
+ border : 0;
}
-:where(article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section){
- display:block
-}
+:where(article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section) { display : block; }
-:where(body){
- line-height:1
-}
+:where(body) { line-height : 1; }
-:where(ol,ul){
- list-style:none
-}
+:where(ol,ul) { list-style : none; }
-:where(blockquote,q){
- quotes:none
-}
+:where(blockquote,q) { quotes : none; }
-:where(blockquote:before,blockquote:after,q:before,q:after){
- content:none
-}
+:where(blockquote::before,blockquote::after,q::before,q::after) { content : none; }
-:where(table){
- border-collapse:collapse;border-spacing:0
+:where(table) {border-spacing : 0;
+ border-collapse : collapse;
}
:where(button) {
- background-color: unset;
- text-transform: unset;
- color: unset;
+ color : unset;
+ text-transform : unset;
+ background-color : unset;
}
diff --git a/shared/naturalcrit/styles/tooltip.less b/shared/naturalcrit/styles/tooltip.less
index 078cfd0c1..b21439486 100644
--- a/shared/naturalcrit/styles/tooltip.less
+++ b/shared/naturalcrit/styles/tooltip.less
@@ -2,116 +2,115 @@
@tooltipColor : #383838;
@arrowSize : 6px;
@arrowPosition : 18px;
-[data-tooltip]{
+[data-tooltip] {
.tooltip(attr(data-tooltip));
}
-[data-tooltip-top]{
+[data-tooltip-top] {
.tooltipTop(attr(data-tooltip-top));
}
-[data-tooltip-bottom]{
+[data-tooltip-bottom] {
.tooltipBottom(attr(data-tooltip-bottom));
}
-[data-tooltip-left]{
+[data-tooltip-left] {
.tooltipLeft(attr(data-tooltip-left));
}
-[data-tooltip-right]{
+[data-tooltip-right] {
.tooltipRight(attr(data-tooltip-right));
}
-.tooltip(@content){
+.tooltip(@content) {
.tooltipBottom(@content);
}
-.tooltipTop(@content){
+.tooltipTop(@content) {
.tooltipBase(@content);
- &:before {
+ &::before {
margin-bottom : -@arrowSize * 2;
border-top-color : @tooltipColor;
}
- &:after{ margin-left: -18px; }
- &:before, &:after{
+ &::after { margin-left : -18px; }
+ &::before, &::after {
bottom : 100%;
left : 50%;
}
- &:hover:after, &:hover:before, &:focus:after, &:focus:before {
+ &:hover::after, &:hover::before, &:focus::after, &:focus::before {
.transform(translateY(-(@arrowSize + 2)));
}
}
-.tooltipBottom(@content){
+.tooltipBottom(@content) {
.tooltipBase(@content);
- &:before {
+ &::before {
margin-top : -@arrowSize * 2;
border-bottom-color : @tooltipColor;
}
- &:after{ margin-left: -18px; }
- &:before, &:after{
+ &::after { margin-left : -18px; }
+ &::before, &::after {
top : 100%;
left : 50%;
}
- &:hover:after, &:hover:before, &:focus:after, &:focus:before {
+ &:hover::after, &:hover::before, &:focus::after, &:focus::before {
.transform(translateY(@arrowSize + 2));
}
}
-.tooltipLeft(@content){
+.tooltipLeft(@content) {
.tooltipBase(@content);
- &:before {
+ &::before {
margin-right : -@arrowSize * 2;
margin-bottom : -@arrowSize;
border-left-color : @tooltipColor;
}
- &:after{ margin-bottom: -14px;}
- &:before, &:after {
+ &::after { margin-bottom : -14px;}
+ &::before, &::after {
right : 100%;
bottom : 50%;
}
- &:hover:after, &:hover:before, &:focus:after, &:focus:before {
+ &:hover::after, &:hover::before, &:focus::after, &:focus::before {
.transform(translateX(-(@arrowSize + 2)));
}
}
-.tooltipRight(@content){
+.tooltipRight(@content) {
.tooltipBase(@content);
- &:before {
+ &::before {
margin-bottom : -@arrowSize;
margin-left : -@arrowSize * 2;
border-right-color : @tooltipColor;
}
- &:after{ margin-bottom: -14px;}
- &:before, &:after {
+ &::after { margin-bottom : -14px;}
+ &::before, &::after {
bottom : 50%;
left : 100%;
}
- &:hover:after, &:hover:before, &:focus:after, &:focus:before {
+ &:hover::after, &:hover::before, &:focus::after, &:focus::before {
.transform(translateX(@arrowSize + 2));
}
}
-.tooltipShow(){
-}
-.tooltipBase(@content){
+.tooltipShow(){ }
+.tooltipBase(@content) {
//position: relative;
- &:before, &:after{
+ &::before, &::after {
.animateAll();
position : absolute;
z-index : 1000000;
- opacity : 0;
pointer-events : none;
+ opacity : 0;
}
//Arrow
- &:before{
- content : '';
+ &::before {
z-index : 1000001;
+ content : '';
background : transparent;
border : @arrowSize solid transparent;
}
//Box
- &:after{
- content : @content;
+ &::after {
visibility : hidden;
padding : 8px 10px;
- background : @tooltipColor;
font-size : 12px;
- color : white;
line-height : 12px;
+ color : white;
white-space : nowrap;
+ content : @content;
+ background : @tooltipColor;
}
- &:hover:before, &:hover:after {
+ &:hover::before, &:hover::after {
visibility : visible;
opacity : 1;
}
diff --git a/tests/markdown/basic.test.js b/tests/markdown/basic.test.js
index e5feec0b3..aaa2adf58 100644
--- a/tests/markdown/basic.test.js
+++ b/tests/markdown/basic.test.js
@@ -1,4 +1,4 @@
-/* eslint-disable max-lines */
+
import Markdown from 'naturalcrit/markdown.js';
diff --git a/tests/markdown/definition-lists.test.js b/tests/markdown/definition-lists.test.js
index 4c754db48..144dad880 100644
--- a/tests/markdown/definition-lists.test.js
+++ b/tests/markdown/definition-lists.test.js
@@ -1,4 +1,4 @@
-/* eslint-disable max-lines */
+
import Markdown from 'naturalcrit/markdown.js';
@@ -92,12 +92,12 @@ describe('Multiline Definition Lists', ()=>{
test('Multiline Definition Term must have at least one non-empty Definition', function() {
const source = 'Term 1\n::';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term 1
\n \n `);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term 1
\n
\n
`);
});
test('Multiline Definition List must have at least one non-newline character after ::', function() {
const source = 'Term 1\n::\nDefinition 1\n\n';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term 1
\n \n \nDefinition 1
`);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term 1
\n
\n
\nDefinition 1
`);
});
});
diff --git a/tests/markdown/hard-breaks.test.js b/tests/markdown/hard-breaks.test.js
index fe646eac9..63bfaef9c 100644
--- a/tests/markdown/hard-breaks.test.js
+++ b/tests/markdown/hard-breaks.test.js
@@ -1,4 +1,4 @@
-/* eslint-disable max-lines */
+
import Markdown from 'naturalcrit/markdown.js';
@@ -6,37 +6,37 @@ describe('Hard Breaks', ()=>{
test('Single Break', function() {
const source = ':\n\n';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(` `);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
test('Double Break', function() {
const source = '::\n\n';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(` \n `);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
`);
});
test('Triple Break', function() {
const source = ':::\n\n';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(` \n \n `);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
`);
});
test('Many Break', function() {
const source = '::::::::::\n\n';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(` \n \n \n \n \n \n \n \n \n `);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
\n
\n
\n
\n
\n
\n
\n
`);
});
test('Multiple sets of Breaks', function() {
const source = ':::\n:::\n:::';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(` \n \n \n \n \n \n \n \n `);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
\n
\n
\n
\n
\n
\n
`);
});
test('Break directly between two paragraphs', function() {
const source = 'Line 1\n::\nLine 2';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Line 1
\n \n \nLine 2
`);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Line 1
\n
\n
\nLine 2
`);
});
test('Ignored inside a code block', function() {
diff --git a/tests/markdown/non-breaking-spaces.test.js b/tests/markdown/non-breaking-spaces.test.js
index 9dad4eb0f..e498645a6 100644
--- a/tests/markdown/non-breaking-spaces.test.js
+++ b/tests/markdown/non-breaking-spaces.test.js
@@ -1,72 +1,24 @@
-/* eslint-disable max-lines */
+
import Markdown from 'naturalcrit/markdown.js';
-describe('Non-Breaking Spaces', ()=>{
- test('Single Space', function() {
- const source = ':>\n\n';
- const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
- });
-
- test('Double Space', function() {
- const source = ':>>\n\n';
- const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
- });
-
- test('Triple Space', function() {
- const source = ':>>>\n\n';
- const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
- });
-
- test('Many Space', function() {
- const source = ':>>>>>>>>>>\n\n';
- const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
- });
-
- test('Multiple sets of Spaces', function() {
- const source = ':>>>\n:>>>\n:>>>';
- const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(` \n \n
`);
- });
-
- test('Pair of inline Spaces', function() {
- const source = ':>>:>>';
- const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
- });
-
- test('Space directly between two paragraphs', function() {
- const source = 'Line 1\n:>>\nLine 2';
- const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Line 1\n \nLine 2
`);
- });
-
- test('Ignored inside a code block', function() {
- const source = '```\n\n:>\n\n```\n';
- const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`\n:>\n `);
- });
-
+describe('Non-Breaking Spaces Interactions', ()=>{
test('I am actually a single-line definition list!', function() {
const source = 'Term ::> Definition 1\n';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term > Definition 1 \n `);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term > Definition 1 \n `);
});
test('I am actually a definition list!', function() {
const source = 'Term\n::> Definition 1\n';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term \n> Definition 1 `);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term \n> Definition 1 `);
});
test('I am actually a two-term definition list!', function() {
const source = 'Term\n::> Definition 1\n::>> Definition 2';
const rendered = Markdown.render(source).trim();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term \n> Definition 1 \n>> Definition 2 `);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Term \n> Definition 1 \n>> Definition 2 `);
});
});
diff --git a/tests/markdown/paragraph-justification.test.js b/tests/markdown/paragraph-justification.test.js
index 48b311e85..7876f5a26 100644
--- a/tests/markdown/paragraph-justification.test.js
+++ b/tests/markdown/paragraph-justification.test.js
@@ -1,4 +1,4 @@
-/* eslint-disable max-lines */
+
import Markdown from 'naturalcrit/markdown.js';
diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js
index 41259da7e..ea98fe56c 100644
--- a/tests/markdown/variables.test.js
+++ b/tests/markdown/variables.test.js
@@ -370,6 +370,30 @@ describe('Cross-page variables', ()=>{
const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns();
expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('two
one
\\pagetwo
');
});
+
+ it('Page numbering across pages : default', function() {
+ const source0 = `$[HB_pageNumber]\n\n`;
+ const source1 = `$[HB_pageNumber]\n\n`;
+ renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up
+ const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns();
+ expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('1
\\page2
');
+ });
+
+ it('Page numbering across pages : custom page number (Number)', function() {
+ const source0 = `[HB_pageNumber]:100\n\n$[HB_pageNumber]\n\n`;
+ const source1 = `$[HB_pageNumber]\n\n`;
+ renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up
+ const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns();
+ expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('100
\\page101
');
+ });
+
+ it('Page numbering across pages : custom page number (NaN)', function() {
+ const source0 = `[HB_pageNumber]:a\n\n$[HB_pageNumber]\n\n`;
+ const source1 = `$[HB_pageNumber]\n\n`;
+ renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up
+ const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns();
+ expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('a
\\pagea
');
+ });
});
describe('Math function parameter handling', ()=>{
@@ -410,4 +434,102 @@ describe('Regression Tests', ()=>{
const rendered = Markdown.render(source).trimReturns();
expect(rendered).toBe('title 1 title 2 title 3 title 4 foo Ipsum ) )
');
});
+
+ it('Handle Extra spaces in image alt-text 1', function(){
+ const source='';
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('
');
+ });
+
+ it('Handle Extra spaces in image alt-text 2', function(){
+ const source='';
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('
');
+ });
+
+ it('Handle Extra spaces in image alt-text 3', function(){
+ const source='';
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('
');
+ });
+
+ it('Handle Extra spaces in image alt-text 4', function(){
+ const source='{height=20%,width=20%}';
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('
');
+ });
+});
+
+describe('Custom Math Function Tests', ()=>{
+ it('Sign Test', function() {
+ const source = `[a]: 13\n\n[b]: -11\n\nPositive: $[sign(a)]\n\nNegative: $[sign(b)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Positive: +
Negative: -
');
+ });
+
+ it('Signed Test', function() {
+ const source = `[a]: 13\n\n[b]: -11\n\nPositive: $[signed(a)]\n\nNegative: $[signed(b)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Positive: +13
Negative: -11
');
+ });
+
+ it('Roman Numerals Test', function() {
+ const source = `[a]: 18\n\nRoman Numeral: $[toRomans(a)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Roman Numeral: XVIII
');
+ });
+
+ it('Roman Numerals Test - Uppercase', function() {
+ const source = `[a]: 18\n\nRoman Numeral: $[toRomansUpper(a)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Roman Numeral: XVIII
');
+ });
+
+ it('Roman Numerals Test - Lowercase', function() {
+ const source = `[a]: 18\n\nRoman Numeral: $[toRomansLower(a)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Roman Numeral: xviii
');
+ });
+
+ it('Number to Characters Test', function() {
+ const source = `[a]: 18\n\n[b]: 39\n\nCharacters: $[toChar(a)] $[toChar(b)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Characters: R AM
');
+ });
+
+ it('Number to Characters Test - Uppercase', function() {
+ const source = `[a]: 18\n\n[b]: 39\n\nCharacters: $[toCharUpper(a)] $[toCharUpper(b)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Characters: R AM
');
+ });
+
+ it('Number to Characters Test - Lowercase', function() {
+ const source = `[a]: 18\n\n[b]: 39\n\nCharacters: $[toCharLower(a)] $[toCharLower(b)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Characters: r am
');
+ });
+
+ it('Number to Words Test', function() {
+ const source = `[a]: 80085\n\nWords: $[toWords(a)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Words: eighty thousand and eighty-five
');
+ });
+
+ it('Number to Words Test - Uppercase', function() {
+ const source = `[a]: 80085\n\nWords: $[toWordsUpper(a)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Words: EIGHTY THOUSAND AND EIGHTY-FIVE
');
+ });
+
+ it('Number to Words Test - Lowercase', function() {
+ const source = `[a]: 80085\n\nWords: $[toWordsLower(a)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Words: eighty thousand and eighty-five
');
+ });
+
+ it('Number to Words Test - Capitalized', function() {
+ const source = `[a]: 80085\n\nWords: $[toWordsCaps(a)]`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered).toBe('Words: Eighty Thousand And Eighty-Five
');
+ });
});
\ No newline at end of file
diff --git a/themes/Legacy/5ePHB/style.less b/themes/Legacy/5ePHB/style.less
index 4ebfbf840..41524c74c 100644
--- a/themes/Legacy/5ePHB/style.less
+++ b/themes/Legacy/5ePHB/style.less
@@ -9,26 +9,22 @@
@headerText : #58180D; // Dark maroon
@monsterStatBackground : #FDF1DC; // Lighter parchment
@captionText : #766649; // Brown
-@page { margin: 0; }
-body {
- counter-reset : phb-page-numbers;
-}
-*{
- -webkit-print-color-adjust : exact;
-}
-.useSansSerif(){
- font-family : ScalySans;
- em{
- font-family : ScalySans;
+@page { margin : 0; }
+body { counter-reset : phb-page-numbers; }
+* { -webkit-print-color-adjust : exact; }
+.useSansSerif() {
+ font-family : 'ScalySans';
+ em {
+ font-family : 'ScalySans';
font-style : italic;
}
- strong{
- font-family : ScalySans;
+ strong {
+ font-family : 'ScalySans';
font-weight : 800;
letter-spacing : -0.02em;
}
}
-.useColumns(@multiplier : 1){
+.useColumns(@multiplier : 1) {
column-count : 2;
column-fill : auto;
column-gap : 1cm;
@@ -40,21 +36,21 @@ body {
-webkit-column-gap : 1cm;
-moz-column-gap : 1cm;
}
-.phb, .page{
+.phb, .page {
.useColumns();
- counter-increment : phb-page-numbers;
position : relative;
z-index : 15;
box-sizing : border-box;
- overflow : hidden;
- height : 279.4mm;
width : 215.9mm;
+ height : 279.4mm;
padding : 1.0cm 1.7cm;
padding-bottom : 1.5cm;
+ overflow : hidden;
+ font-family : 'BookSanity';
+ font-size : 0.317cm;
+ counter-increment : phb-page-numbers;
background-color : @background;
background-image : @backgroundImage;
- font-family : BookSanity;
- font-size : 0.317cm;
text-rendering : optimizeLegibility;
page-break-before : always;
page-break-after : always;
@@ -63,199 +59,175 @@ body {
contain-intrinsic-size : auto none;
}
-.phb{
+.phb {
//*****************************
// * BASE
// *****************************/
- p{
+ p {
padding-bottom : 0.8em;
line-height : 1.269em;
- &+p{
- margin-top : -0.8em;
- }
+ & + p { margin-top : -0.8em; }
}
- ul{
- margin-bottom : 0.8em;
+ ul {
padding-left : 1.4em;
+ margin-bottom : 0.8em;
line-height : 1.269em;
list-style-position : outside;
list-style-type : disc;
}
- ol{
- margin-bottom : 0.8em;
+ ol {
padding-left : 1.4em;
+ margin-bottom : 0.8em;
line-height : 1.269em;
list-style-position : outside;
list-style-type : decimal;
}
//Indents after p or lists
- p+p, ul+p, ol+p{
- text-indent : 1em;
- }
- img{
- z-index : -1;
- }
- strong{
+ p + p, ul + p, ol + p { text-indent : 1em; }
+ img { z-index : -1; }
+ strong {
font-weight : bold;
letter-spacing : 0.03em;
}
- em{
- font-style : italic;
- }
- sup{
+ em { font-style : italic; }
+ sup {
+ font-size : smaller;
+ line-height : 0;
vertical-align : super;
- font-size : smaller;
- line-height : 0;
}
- sub{
- vertical-align : sub;
+ sub {
font-size : smaller;
line-height : 0;
+ vertical-align : sub;
}
//*****************************
// * HEADERS
// *****************************/
- h1,h2,h3,h4{
+ h1,h2,h3,h4 {
margin-top : 0.2em;
margin-bottom : 0.2em;
- font-family : MrJeeves;
+ font-family : 'MrJeeves';
font-weight : 800;
color : @headerText;
}
- h1{
+ h1 {
column-span : all;
font-size : 0.987cm;
-webkit-column-span : all;
-moz-column-span : all;
- &+p::first-letter{
+ & + p::first-letter {
float : left;
- font-family : Solberry;
+ font-family : 'Solberry';
font-size : 10em;
- color : #222;
line-height : 0.795em;
+ color : #222222;
}
}
- h2{
- font-size : 0.705cm;
- }
- h3{
+ h2 { font-size : 0.705cm; }
+ h3 {
font-size : 0.529cm;
border-bottom : 2px solid @headerUnderline;
}
- h4{
+ h4 {
margin-bottom : 0.00em;
font-size : 0.458cm;
}
- h5{
+ h5 {
margin-bottom : 0.2em;
- font-family : ScalySansSmallCaps;
+ font-family : 'ScalySansSmallCaps';
font-size : 0.423cm;
font-weight : 900;
}
//*****************************
// * TABLE
// *****************************/
- table{
+ table {
.useSansSerif();
width : 100%;
margin-bottom : 1em;
font-size : 10pt;
- thead{
- display: table-row-group;
+ thead {
+ display : table-row-group;
font-weight : 800;
- th{
- vertical-align : bottom;
- padding-bottom : 0.3em;
+ th {
padding-right : 0.1em;
+ padding-bottom : 0.3em;
padding-left : 0.1em;
+ vertical-align : bottom;
}
}
- tbody{
- tr{
- td{
- padding : 0.3em 0.1em;
- }
- &:nth-child(odd){
- background-color : @noteGreen;
- }
+ tbody {
+ tr {
+ td { padding : 0.3em 0.1em; }
+ &:nth-child(odd) { background-color : @noteGreen; }
}
}
}
//*****************************
// * NOTE
// *****************************/
- blockquote{
+ blockquote {
.useSansSerif();
box-sizing : border-box;
- margin-bottom : 1em;
padding : 5px 10px;
+ margin-bottom : 1em;
background-color : @noteGreen;
border-style : solid;
border-width : 11px;
border-image : @noteBorderImage 11;
border-image-outset : 9px 0px;
- box-shadow : 1px 4px 14px #888;
- p, ul{
+ box-shadow : 1px 4px 14px #888888;
+ p, ul {
font-size : 0.352cm;
line-height : 1.083em;
}
}
//If a note starts a column, give it space at the top to render border
- pre+blockquote, h2+blockquote, h3+blockquote, h4+blockquote, h5+blockquote {
- margin-top : 13px;
- }
+ pre + blockquote, h2 + blockquote, h3 + blockquote, h4 + blockquote, h5 + blockquote { margin-top : 13px; }
//*****************************
// * MONSTER STAT BLOCK
// *****************************/
- hr+blockquote{
+ hr+blockquote {
position : relative;
padding-top : 15px;
background-color : @monsterStatBackground;
border-style : solid;
border-width : 10px;
border-image : @monsterBorderImageLegacy 10;
- h2{
+ h2 {
margin-top : -8px;
margin-bottom : 0px;
- &+p{
- padding-bottom : 0px;
- }
+ & + p { padding-bottom : 0px; }
}
- h3{
- font-family : ScalySans;
- font-weight : 400;
+ h3 {
+ font-family : 'ScalySans';
+ font-weight : normal;
border-bottom : 1px solid @headerText;
}
- hr+ul{
- color : @headerText;
- }
- ul{
+ hr + ul { color : @headerText; }
+ ul {
.useSansSerif();
padding-left : 1em;
font-size : 0.352cm;
}
// Monster Ability table
- hr+table{
+ hr + table {
margin : 0;
background-color : transparent;
border-style : none;
border-image : none;
- tbody{
- tr:nth-child(odd), tr:nth-child(even){
- background-color : transparent;
- }
+ tbody {
+ tr:nth-child(odd), tr:nth-child(even) { background-color : transparent; }
}
}
- table{
- color : @headerText;
- }
- p+p{
- margin-top : 0em;
+ table { color : @headerText; }
+ p + p {
padding-bottom : 0.5em;
+ margin-top : 0em;
text-indent : 0em;
}
//Triangle dividers
- hr{
+ hr {
visibility : visible;
height : 6px;
margin : 4px 0px;
@@ -265,100 +237,90 @@ body {
}
}
//Full Width
- hr+hr+blockquote{
+ hr + hr + blockquote {
.useColumns(0.96);
column-fill : balance;
}
//*****************************
// * FOOTER
// *****************************/
- &:after{
- content : "";
+ &:after {
position : absolute;
bottom : 0px;
left : 0px;
z-index : 100;
- height : 50px;
width : 100%;
+ height : 50px;
+ content : '';
background-image : @footerAccentImage;
background-size : cover;
}
- &:nth-child(even){
- &:after{
- transform : scaleX(-1);
- }
- .pageNumber{
- left : 2px;
- }
- .footnote{
+ &:nth-child(even) {
+ &::after { transform : scaleX(-1); }
+ .pageNumber { left : 2px; }
+ .footnote {
left : 80px;
text-align : left;
}
}
- .pageNumber{
+ .pageNumber {
position : absolute;
right : 2px;
bottom : 22px;
width : 50px;
font-size : 0.9em;
- color : #c9ad6a;
+ color : #C9AD6A;
text-align : center;
- &.auto::after {
- content : counter(phb-page-numbers);
- }
+ &.auto::after { content : counter(phb-page-numbers); }
}
- .footnote{
+ .footnote {
position : absolute;
right : 80px;
bottom : 32px;
z-index : 150;
width : 200px;
font-size : 0.8em;
- color : #c9ad6a;
+ color : #C9AD6A;
text-align : right;
}
//*****************************
// * EXTRAS
// *****************************/
- hr{
+ hr {
visibility : hidden;
margin : 0px;
}
//Modified unorder list, used in spells
- hr+ul{
- margin-bottom : 0.5em;
+ hr + ul {
padding-left : 1em;
+ margin-bottom : 0.5em;
text-indent : -1em;
list-style-type : none;
}
//Column Break
- pre, code{
+ pre, code {
visibility : hidden;
-webkit-column-break-after : always;
break-after : always;
-moz-column-break-after : always;
}
//Avoid breaking up
- p,blockquote,table{
+ p,blockquote,table {
z-index : 15;
-webkit-column-break-inside : avoid;
page-break-inside : avoid;
break-inside : avoid;
}
//Better spacing for spell blocks
- h4+p+hr+ul{
- margin-top : -0.5em
- }
+ h4 + p + hr + ul { margin-top : -0.5em; }
//Text indent right after table
- table+p{
- text-indent : 1em;
- }
+ table + p { text-indent : 1em; }
// Nested lists
- ul ul,ol ol,ul ol,ol ul{
+ ul ul,ol ol,ul ol,ol ul {
margin-bottom : 0px;
margin-left : 1.5em;
}
- li{
+ li {
-webkit-column-break-inside : avoid;
page-break-inside : avoid;
break-inside : avoid;
@@ -367,89 +329,81 @@ body {
//*****************************
// * SPELL LIST
// *****************************/
-.phb .spellList{
+.phb .spellList {
.useSansSerif();
column-count : 4;
- column-span : all;
-webkit-column-span : all;
-moz-column-span : all;
- ul+h5{
- margin-top : 15px;
- }
- p, ul{
+ column-span : all;
+ ul + h5 { margin-top : 15px; }
+ p, ul {
font-size : 0.352cm;
line-height : 1.263em;
}
- ul{
- margin-bottom : 0.5em;
+ ul {
padding-left : 1em;
+ margin-bottom : 0.5em;
text-indent : -1em;
list-style-type : none;
+ break-inside : auto;
-webkit-column-break-inside : auto;
page-break-inside : auto;
- break-inside : auto;
}
}
//*****************************
// * WIDE
// *****************************/
-.phb .wide{
- column-span : all;
+.phb .wide {
-webkit-column-span : all;
-moz-column-span : all;
+ column-span : all;
}
//*****************************
// * CLASS TABLE
// *****************************/
-.phb .classTable{
+.phb .classTable {
margin-top : 25px;
margin-bottom : 40px;
border-collapse : separate;
background-color : white;
border : initial;
border-style : solid;
+ border-image-source : @frameBorderImage;
+ border-image-slice : 150 200 150 200;
+ border-image-width : 47px;
border-image-outset : 25px 17px;
border-image-repeat : stretch;
- border-image-slice : 150 200 150 200;
- border-image-source : @frameBorderImage;
- border-image-width : 47px;
- h5{
- margin-bottom : 10px;
- }
+ h5 { margin-bottom : 10px; }
}
//************************************
// * DESCRIPTIVE TEXT BOX
// ************************************/
-.phb .descriptive{
+.phb .descriptive {
margin-bottom : 1em;
- background-color : #faf7ea;
- font-family : ScalySans;
+ font-family : 'ScalySans';
+ background-color : #FAF7EA;
border-style : solid;
border-width : 7px;
border-image : @descriptiveBoxImage 12 stretch;
border-image-outset : 4px;
- box-shadow : 0px 0px 6px #faf7ea;
- p{
+ box-shadow : 0px 0px 6px #FAF7EA;
+ p {
display : block;
padding-bottom : 0px;
line-height : 1.47em;
}
- p + p {
- padding-top : .8em;
- }
+ p + p { padding-top : 0.8em; }
em {
- font-family : ScalySans;
+ font-family : 'ScalySans';
font-style : italic;
}
strong {
- font-family : ScalySans;
+ font-family : 'ScalySans';
font-weight : 800;
letter-spacing : -0.02em;
}
}
-.phb pre+.descriptive{
- margin-top : 8px;
-}
+.phb pre + .descriptive { margin-top : 8px; }
//*****************************
// * ARTIST CREDIT BLOCK
@@ -457,47 +411,41 @@ body {
.phb {
.artist {
position : absolute;
- text-align : center;
- font-family : WalterTurncoat;
+ font-family : 'WalterTurncoat';
font-size : 0.27cm;
color : @captionText;
+ text-align : center;
p, p + p {
margin : unset;
- text-indent : unset;
line-height : 0.941em;
+ text-indent : unset;
}
- h5 {
+ h5 {
+ font-family : 'WalterTurncoat';
font-size : 1.3em;
- font-family : WalterTurncoat;
}
- a{
+ a {
color : inherit;
text-decoration : unset;
- &:hover {
- text-decoration : underline;
- }
+ &:hover { text-decoration : underline; }
}
}
}
//*****************************
// * TABLE OF CONTENTS
// *****************************/
-.phb .toc{
+.phb .toc {
-webkit-column-break-inside : avoid;
page-break-inside : avoid;
break-inside : avoid;
- a{
+ a {
color : black;
text-decoration : none;
- &:hover{
- text-decoration : underline;
- }
+ &:hover { text-decoration : underline; }
}
- ul{
+ ul {
padding-left : 0;
list-style-type : none;
}
- &>ul>li{
- margin-bottom : 10px;
- }
+ & > ul > li { margin-bottom : 10px; }
}
diff --git a/themes/V3/5eDMG/snippets.js b/themes/V3/5eDMG/snippets.js
index 636befb60..bad5e8e6a 100644
--- a/themes/V3/5eDMG/snippets.js
+++ b/themes/V3/5eDMG/snippets.js
@@ -1,4 +1,4 @@
-/* eslint-disable max-lines */
+
module.exports = [
];
diff --git a/themes/V3/5eDMG/style.less b/themes/V3/5eDMG/style.less
index 2ced98312..d79533c2c 100644
--- a/themes/V3/5eDMG/style.less
+++ b/themes/V3/5eDMG/style.less
@@ -7,37 +7,29 @@
}
.page {
- background-image : url(/assets/DMG_background.png);
+ background-image : url('/assets/DMG_background.png');
background-size : cover;
- /*TABLES WITHIN NOTES*/
- .note table tbody tr:nth-child(odd) {
- background:#fff;
- }
+ /* TABLES WITHIN NOTES */
+ .note table tbody tr:nth-child(odd) { background : #FFFFFF; }
- /*DROP CAP*/
+ /* DROP CAP */
h1 + p::first-letter {
- background-image: unset;
- color:black;
+ color : black;
+ background-image : unset;
}
- .quote p:first-child::first-line {
- all: unset;
+ .quote p:first-child::first-line { all : unset; }
+
+ &::after {
+ height : 58px;
+ background-image : url('/assets/DMG_footerAccent.png');
}
- &:after {
- background-image : url(/assets/DMG_footerAccent.png);
- height: 58px;
- }
-
- .footnote {
- bottom : 40px;
- }
+ .footnote { bottom : 40px; }
}
.page:has(.partCover) {
- .partCover {
- background-image: @partCoverHeaderDMG;
- }
+ .partCover { background-image : @partCoverHeaderDMG; }
}
diff --git a/themes/V3/5ePHB/snippets.js b/themes/V3/5ePHB/snippets.js
index dbcdc6f2a..27ea62bea 100644
--- a/themes/V3/5ePHB/snippets.js
+++ b/themes/V3/5ePHB/snippets.js
@@ -6,164 +6,12 @@ const MonsterBlockGen = require('./snippets/monsterblock.gen.js');
const scriptGen = require('./snippets/script.gen.js');
const ClassFeatureGen = require('./snippets/classfeature.gen.js');
const CoverPageGen = require('./snippets/coverpage.gen.js');
-const TableOfContentsGen = require('./snippets/tableOfContents.gen.js');
-const indexGen = require('./snippets/index.gen.js');
const QuoteGen = require('./snippets/quote.gen.js');
const dedent = require('dedent-tabs').default;
module.exports = [
-
- {
- groupName : 'Text Editor',
- icon : 'fas fa-pencil-alt',
- view : 'text',
- snippets : [
- {
- name : 'Table of Contents',
- icon : 'fas fa-book',
- gen : TableOfContentsGen,
- experimental : true,
- subsnippets : [
- {
- name : 'Generate Table of Contents',
- icon : 'fas fa-book',
- gen : TableOfContentsGen,
- experimental : true
- },
- {
- name : 'Table of Contents Individual Inclusion',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocInclude# CHANGE # to your header level
- }}\n`,
- subsnippets : [
- {
- name : 'Individual Inclusion H1',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocIncludeH1 \n
- }}\n`,
- },
- {
- name : 'Individual Inclusion H2',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocIncludeH2 \n
- }}\n`,
- },
- {
- name : 'Individual Inclusion H3',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocIncludeH3 \n
- }}\n`,
- },
- {
- name : 'Individual Inclusion H4',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocIncludeH4 \n
- }}\n`,
- },
- {
- name : 'Individual Inclusion H5',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocIncludeH5 \n
- }}\n`,
- },
- {
- name : 'Individual Inclusion H6',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocIncludeH6 \n
- }}\n`,
- }
- ]
- },
- {
- name : 'Table of Contents Range Inclusion',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocDepthH3
- }}\n`,
- subsnippets : [
- {
- name : 'Include in ToC up to H3',
- icon : 'fas fa-dice-three',
- gen : dedent `\n{{tocDepthH3
- }}\n`,
-
- },
- {
- name : 'Include in ToC up to H4',
- icon : 'fas fa-dice-four',
- gen : dedent `\n{{tocDepthH4
- }}\n`,
- },
- {
- name : 'Include in ToC up to H5',
- icon : 'fas fa-dice-five',
- gen : dedent `\n{{tocDepthH5
- }}\n`,
- },
- {
- name : 'Include in ToC up to H6',
- icon : 'fas fa-dice-six',
- gen : dedent `\n{{tocDepthH6
- }}\n`,
- },
- ]
- },
- {
- name : 'Table of Contents Individual Exclusion',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocExcludeH1 \n
- }}\n`,
- subsnippets : [
- {
- name : 'Individual Exclusion H1',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocExcludeH1 \n
- }}\n`,
- },
- {
- name : 'Individual Exclusion H2',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocExcludeH2 \n
- }}\n`,
- },
- {
- name : 'Individual Exclusion H3',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocExcludeH3 \n
- }}\n`,
- },
- {
- name : 'Individual Exclusion H4',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocExcludeH4 \n
- }}\n`,
- },
- {
- name : 'Individual Exclusion H5',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocExcludeH5 \n
- }}\n`,
- },
- {
- name : 'Individual Exclusion H6',
- icon : 'fas fa-book',
- gen : dedent `\n{{tocExcludeH6 \n
- }}\n`,
- },
- ]
- },
-
- ]
- },
- {
- name : 'Index',
- icon : 'fas fa-bars',
- gen : indexGen,
- experimental : true
- }
- ]
- },
{
groupName : 'Style Editor',
icon : 'fas fa-pencil-alt',
@@ -192,70 +40,9 @@ module.exports = [
line-height: 1em;
}\n\n`
},
- {
- name : 'Table of Contents Toggles',
- icon : 'fas fa-book',
- subsnippets : [
- {
- name : 'Enable H1-H4 all pages',
- icon : 'fas fa-dice-four',
- gen : `.page {\n\th4 {--TOC: include; }\n}\n\n`,
- },
- {
- name : 'Enable H1-H5 all pages',
- icon : 'fas fa-dice-five',
- gen : `.page {\n\th4, h5 {--TOC: include; }\n}\n\n`,
- },
- {
- name : 'Enable H1-H6 all pages',
- icon : 'fas fa-dice-six',
- gen : `.page {\n\th4, h5, h6 {--TOC: include; }\n}\n\n`,
- },
- ]
- }
]
},
-
- /*********************** IMAGES *******************/
- {
- groupName : 'Images',
- icon : 'fas fa-images',
- view : 'text',
- snippets : [
- {
- name : 'Image',
- icon : 'fas fa-image',
- gen : dedent`
-  {width:325px,mix-blend-mode:multiply}
-
- {{artist,position:relative,top:-230px,left:10px,margin-bottom:-30px
- ##### Cat Warrior
- [Kyoung Hwan Kim](https://www.artstation.com/tahra)
- }}`
- },
- {
- name : 'Background Image',
- icon : 'fas fa-tree',
- gen : dedent`
-  {position:absolute,top:50px,right:30px,width:280px}
-
- {{artist,top:80px,right:30px
- ##### Homebrew Mug
- [naturalcrit](https://homebrew.naturalcrit.com)
- }}`
- },
- {
- name : 'Watermark',
- icon : 'fas fa-id-card',
- gen : dedent`
- {{watermark Homebrewery}}\n`
- },
- ]
- },
-
-
/************************* PHB ********************/
-
{
groupName : 'PHB',
icon : 'fas fa-book',
@@ -450,9 +237,6 @@ module.exports = [
]
},
-
-
-
/**************** PAGE *************/
{
diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less
index 5eebcb12e..555866ba4 100644
--- a/themes/V3/5ePHB/style.less
+++ b/themes/V3/5ePHB/style.less
@@ -305,12 +305,12 @@
margin-left : -0.16cm;
background-color : var(--HB_Color_MonsterStatBackground);
background-image : @monsterBlockBackground;
- background-blend-mode : overlay;
border-style : solid;
border-width : 7px 6px;
border-image : @monsterBorderImage 14 round;
border-image-outset : 0px 2px;
box-shadow : 1px 4px 14px #888888;
+ background-blend-mode : overlay;
}
position : relative;
@@ -335,9 +335,9 @@
//Triangle dividers
hr {
+ visibility : visible;
height : 6px;
margin : 0.12cm 0cm;
- visibility : visible;
background-image : @redTriangleImage;
background-size : 100% 100%;
border : none;
@@ -355,8 +355,8 @@
}
.bonus {
- float: right;
- padding-right: 0.5em;
+ float : right;
+ padding-right : 0.5em;
}
// Monster Ability table
@@ -456,8 +456,8 @@
// * EXTRAS
// *****************************/
hr {
- margin : 0px;
visibility : hidden;
+ margin : 0px;
}
//Text indent right after table
table + p { text-indent : 1em; }
@@ -525,10 +525,10 @@
content : '';
background-image : @classTableDecoration,
@classTableDecoration;
- filter : drop-shadow(0px 0px 1px #C8C5C080);
background-repeat : no-repeat, no-repeat;
background-position : top, bottom;
background-size : contain, contain;
+ filter : drop-shadow(0px 0px 1px #C8C5C080);
transform : translateY(-50%) translateX(-50%);
}
&.decoration.wide::before {
@@ -545,39 +545,40 @@
columns : 1;
text-align : center;
&::after { display : none; }
+ .frontCover { position : absolute; }
h1 {
- margin-top : 1.2cm;
- margin-bottom : 0;
- font-family : 'NodestoCapsCondensed';
- font-size : 2.245cm;
- font-weight : normal;
- line-height : 1.9cm;
- color : white;
- text-shadow : unset;
- text-transform : uppercase;
- -webkit-text-stroke: 0.2cm black;
- paint-order:stroke;
+ margin-top : 1.55cm;
+ margin-bottom : 0;
+ font-family : 'NodestoCapsCondensed';
+ font-size : 2.245cm;
+ font-weight : normal;
+ line-height : 1.9cm;
+ color : white;
+ text-transform : uppercase;
+ text-shadow : unset;
+ -webkit-text-stroke : 0.2cm black;
+ paint-order : stroke;
}
h2 {
- font-family : 'NodestoCapsCondensed';
- font-size : 0.85cm;
- font-weight : normal;
- color : white;
- letter-spacing : 0.1cm;
- -webkit-text-stroke: 0.14cm black;
- paint-order:stroke;
+ font-family : 'NodestoCapsCondensed';
+ font-size : 0.85cm;
+ font-weight : normal;
+ color : white;
+ letter-spacing : 0.1cm;
+ -webkit-text-stroke : 0.14cm black;
+ paint-order : stroke;
}
hr {
position : relative;
display : block;
+ visibility : visible;
width : 12cm;
height : 0.5cm;
margin : auto;
- visibility : visible;
background-image : @horizontalRule;
- filter : drop-shadow(0 0 3px black);
background-size : 100% 100%;
border : none;
+ filter : drop-shadow(0 0 3px black);
}
.banner {
position : absolute;
@@ -600,19 +601,19 @@
filter : drop-shadow(2px 2px 2px black);
}
.footnote {
- position : absolute;
- right : 0;
- bottom : 1.3cm;
- left : 0;
- width : 70%;
- margin-right : auto;
- margin-left : auto;
- font-family : 'Overpass';
- font-size : 0.496cm;
- color : white;
- text-align : center;
- -webkit-text-stroke: 0.1cm black;
- paint-order:stroke;
+ position : absolute;
+ right : 0;
+ bottom : 1.3cm;
+ left : 0;
+ width : 70%;
+ margin-right : auto;
+ margin-left : auto;
+ font-family : 'Overpass';
+ font-size : 0.496cm;
+ color : white;
+ text-align : center;
+ -webkit-text-stroke : 0.1cm black;
+ paint-order : stroke;
}
.logo {
position : absolute;
@@ -620,9 +621,7 @@
right : 0;
left : 0;
filter : drop-shadow(0 0 0.075cm black);
- img {
- height : 2cm;
- }
+ img { height : 2cm; }
}
}
// *****************************
@@ -632,8 +631,9 @@
columns : 1;
text-align : center;
&::after { display : none; }
+ .insideCover { position : absolute; }
h1 {
- margin-top : 1.2cm;
+ margin-top : 1.55cm;
margin-bottom : 0;
font-family : 'NodestoCapsCondensed';
font-size : 2.1cm;
@@ -650,10 +650,10 @@
hr {
position : relative;
display : block;
+ visibility : visible;
width : 12cm;
height : 0.5cm;
margin : auto;
- visibility : visible;
background-image : @horizontalRule;
background-size : 100% 100%;
border : none;
@@ -664,19 +664,17 @@
bottom : 1cm;
left : 0;
height : 2cm;
- img {
- height : 2cm;
- }
+ img { height : 2cm; }
}
}
// *****************************
// * BACK COVER
// *****************************/
.page:has(.backCover) {
- padding : 2.25cm 1.3cm 2cm 1.3cm;
- color : #FFFFFF;
- columns : 1;
+ padding : 2.25cm 1.3cm 2cm 1.3cm;
line-height : 1.4em;
+ color : #FFFFFF;
+ columns : 1;
&::after { display : none; }
.columnWrapper { width : 7.6cm; }
.backCover {
@@ -687,6 +685,7 @@
background-repeat : no-repeat;
background-size : contain;
}
+ .blank { height : 1.4em; }
h1 {
margin-bottom : 0.3cm;
font-family : 'NodestoCapsCondensed';
@@ -704,12 +703,12 @@
height : 100%;
}
hr {
+ visibility : visible;
width : 4.5cm;
height : 0.53cm;
margin-top : 1.1cm;
margin-right : auto;
margin-left : auto;
- visibility : visible;
background-image : @horizontalRule;
background-size : 100% 100%;
border : none;
@@ -792,54 +791,13 @@
// * TABLE OF CONTENTS
// *****************************/
-// Default Exclusions
-// Anything not excluded is included, default Headers are H1, H2, and H3.
-h4,
-h5,
-h6,
-.page:has(.frontCover),
-.page:has(.backCover),
-.page:has(.insideCover),
-.monster,
-.noToC,
-.toc { --TOC: exclude; }
-
-
-// Brew level default inclusion changes.
-// These add Headers 'back' to inclusion.
-
-//NOTE: DO NOT USE :HAS WITH .PAGES!!! EXTREMELY SLOW TO RENDER ON LARGE DOCS!
-
-// Block level inclusion changes
-// These include either a single (include) or a range (depth)
-.tocIncludeH1 h1 {--TOC: include; }
-.tocIncludeH2 h2 {--TOC: include; }
-.tocIncludeH3 h3 {--TOC: include; }
-.tocIncludeH4 h4 {--TOC: include; }
-.tocIncludeH5 h5 {--TOC: include; }
-.tocIncludeH6 h6 {--TOC: include; }
-
-.tocDepthH2 :is(h1, h2) {--TOC: include; }
-.tocDepthH3 :is(h1, h2, h3) {--TOC: include; }
-.tocDepthH4 :is(h1, h2, h3, h4) {--TOC: include; }
-.tocDepthH5 :is(h1, h2, h3, h4, h5) {--TOC: include; }
-.tocDepthH6 :is(h1, h2, h3, h4, h5, h6) {--TOC: include; }
-
-// Block level exclusion changes
-// These exclude a single block level
-.tocExcludeH1 h1 {--TOC: exclude; }
-.tocExcludeH2 h2 {--TOC: exclude; }
-.tocExcludeH3 h3 {--TOC: exclude; }
-.tocExcludeH4 h4 {--TOC: exclude; }
-.tocExcludeH5 h5 {--TOC: exclude; }
-.tocExcludeH6 h6 {--TOC: exclude; }
+// Additional Default Exclusions
+.monster { --TOC : exclude; }
.page:has(.partCover) {
- --TOC: exclude;
- & h1 {
- --TOC: include;
- }
- }
+ --TOC : exclude;
+ & h1 { --TOC : include; }
+}
.page {
&:has(.toc)::after { display : none; }
@@ -905,9 +863,7 @@ h6,
.useColumns(0.96, @fillMode: balance);
}
}
- .toc.wide li {
- break-inside: auto;
- }
+ .toc.wide li { break-inside : auto; }
}
// *****************************
@@ -932,9 +888,7 @@ h6,
.page h1 + * { margin-top : 0; }
-.page .descriptive.wide + * {
- margin-top: 0;
-}
+.page .descriptive.wide + * { margin-top : 0; }
//*****************************
// * RUNE TABLE
@@ -949,8 +903,8 @@ h6,
width : 1.3cm;
height : 1.3cm;
font-weight : normal;
- text-transform : uppercase;
vertical-align : middle;
+ text-transform : uppercase;
outline : 1px solid #000000;
}
th {
@@ -971,6 +925,7 @@ h6,
}
}
}
+
// *****************************
// * INDEX
// *****************************/
diff --git a/themes/V3/Blank/snippets.js b/themes/V3/Blank/snippets.js
index e92e757cf..c5198fd87 100644
--- a/themes/V3/Blank/snippets.js
+++ b/themes/V3/Blank/snippets.js
@@ -4,6 +4,8 @@ const WatercolorGen = require('./snippets/watercolor.gen.js');
const ImageMaskGen = require('./snippets/imageMask.gen.js');
const FooterGen = require('./snippets/footer.gen.js');
const dedent = require('dedent-tabs').default;
+const TableOfContentsGen = require('./snippets/tableOfContents.gen.js');
+const indexGen = require('./snippets/index.gen.js');
module.exports = [
@@ -36,6 +38,11 @@ module.exports = [
icon : 'fas fa-sort-numeric-down',
gen : '{{pageNumber,auto}}\n'
},
+ {
+ name : 'Variable Auto Page Number',
+ icon : 'fas fa-sort-numeric-down',
+ gen : '{{pageNumber $[HB_pageNumber]}}\n'
+ },
{
name : 'Skip Page Number Increment this Page',
icon : 'fas fa-xmark',
@@ -141,7 +148,53 @@ module.exports = [
[Homebrewery.Naturalcrit.com](https://homebrewery.naturalcrit.com)
}}\n\n`;
},
- }
+ },
+ {
+ name : 'Table of Contents',
+ icon : 'fas fa-book',
+ gen : TableOfContentsGen,
+ experimental : true,
+ subsnippets : [
+ {
+ name : 'Table of Contents',
+ icon : 'fas fa-book',
+ gen : TableOfContentsGen,
+ experimental : true
+ },
+ {
+ name : 'Include in ToC up to H3',
+ icon : 'fas fa-dice-three',
+ gen : dedent `\n{{tocDepthH3
+ }}\n`,
+
+ },
+ {
+ name : 'Include in ToC up to H4',
+ icon : 'fas fa-dice-four',
+ gen : dedent `\n{{tocDepthH4
+ }}\n`,
+ },
+ {
+ name : 'Include in ToC up to H5',
+ icon : 'fas fa-dice-five',
+ gen : dedent `\n{{tocDepthH5
+ }}\n`,
+ },
+ {
+ name : 'Include in ToC up to H6',
+ icon : 'fas fa-dice-six',
+ gen : dedent `\n{{tocDepthH6
+ }}\n`,
+ }
+ ]
+ },
+ {
+ name : 'Index',
+ icon : 'fas fa-bars',
+ gen : indexGen,
+ experimental : true
+ },
+
]
},
{
@@ -153,7 +206,7 @@ module.exports = [
name : 'Add Comment',
icon : 'fas fa-code',
gen : '/* This is a comment that will not be rendered into your brew. */'
- },
+ }
]
},
@@ -438,6 +491,15 @@ module.exports = [
icon : 'fas fa-print',
view : 'style',
snippets : [
+ {
+ name : 'US Letter Page Size',
+ icon : 'far fa-file',
+ gen : dedent`/* US Letter Page Size */
+ .page {
+ width : 215.9mm; /* 8.5in */
+ height : 279.4mm; /* 11in */
+ }\n\n`,
+ },
{
name : 'A3 Page Size',
icon : 'far fa-file',
diff --git a/themes/V3/5ePHB/snippets/index.gen.js b/themes/V3/Blank/snippets/index.gen.js
similarity index 100%
rename from themes/V3/5ePHB/snippets/index.gen.js
rename to themes/V3/Blank/snippets/index.gen.js
diff --git a/themes/V3/5ePHB/snippets/tableOfContents.gen.js b/themes/V3/Blank/snippets/tableOfContents.gen.js
similarity index 100%
rename from themes/V3/5ePHB/snippets/tableOfContents.gen.js
rename to themes/V3/Blank/snippets/tableOfContents.gen.js
diff --git a/themes/V3/Blank/style.less b/themes/V3/Blank/style.less
index 1a22db6a7..01b85326f 100644
--- a/themes/V3/Blank/style.less
+++ b/themes/V3/Blank/style.less
@@ -5,6 +5,7 @@
@import (less) './themes/fonts/iconFonts/diceFont.less';
@import (less) './themes/fonts/iconFonts/gameIcons.less';
@import (less) './themes/fonts/iconFonts/fontAwesome.less';
+@import (less) './themes/fonts/Journal/fonts.less';
:root {
//Colors
@@ -21,9 +22,9 @@ body { counter-reset : page-numbers 0; }
// *****************************/
.page {
.block {
- break-inside : avoid;
display : inline-block;
width : 100%;
+ break-inside : avoid;
img { z-index : 0; }
}
.inline-block {
@@ -58,8 +59,8 @@ body { counter-reset : page-numbers 0; }
content-visibility : auto;
contain-intrinsic-size : auto none;
}
- //*****************************
- // * BASE
+//*****************************
+// * BASE
// *****************************/
.page {
p {
@@ -120,7 +121,7 @@ body { counter-reset : page-numbers 0; }
// * CODE BLOCKS
// ************************************/
code {
- font-family : 'Courier New', "Courier", monospace;
+ font-family : 'Courier New', 'Courier', monospace;
overflow-wrap : break-word;
white-space : pre-wrap;
}
@@ -133,10 +134,10 @@ body { counter-reset : page-numbers 0; }
// * EXTRAS
// *****************************/
.columnSplit {
- margin-top : 0;
visibility : hidden;
- -webkit-column-break-after : always;
+ margin-top : 0;
break-after : always;
+ -webkit-column-break-after : always;
-moz-column-break-after : always;
& + * { margin-top : 0; }
}
@@ -199,11 +200,11 @@ body { counter-reset : page-numbers 0; }
background-color : var(--HB_Color_WatercolorStain); /* default color */
background-size : cover;
-webkit-mask-image : var(--wc);
- -webkit-mask-size : contain;
- -webkit-mask-repeat : no-repeat;
mask-image : var(--wc);
- mask-size : contain;
+ -webkit-mask-repeat : no-repeat;
mask-repeat : no-repeat;
+ -webkit-mask-size : contain;
+ mask-size : contain;
--wc : @watercolor1; /* default image */
}
@@ -231,15 +232,15 @@ body { counter-reset : page-numbers 0; }
height : 200%;
background-image : var(--checkerboard);
background-size : 20px;
- transform : translateY(50%) translateX(-50%) rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY));
-webkit-mask-image : var(--wc), var(--revealer);
- -webkit-mask-repeat : repeat-x;
- -webkit-mask-size : 50%; //Scale only X to fit page width, leave height at aspect ratio, designed to hang off the edge
- -webkit-mask-position : 50% calc(50% - var(--offset));
mask-image : var(--wc);
+ -webkit-mask-repeat : repeat-x;
mask-repeat : repeat-x;
- mask-size : 50%;
+ -webkit-mask-position : 50% calc(50% - var(--offset));
mask-position : 50% calc(50% - var(--offset));
+ -webkit-mask-size : 50%; //Scale only X to fit page width, leave height at aspect ratio, designed to hang off the edge
+ mask-size : 50%;
+ transform : translateY(50%) translateX(-50%) rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY));
--rotation : 0;
--revealer : none;
--checkerboard : none;
@@ -276,19 +277,19 @@ body { counter-reset : page-numbers 0; }
}
&.revealImage {
--revealer : linear-gradient(0deg, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0.2));
- --checkerboard : url("/assets/waterColorMasks/missingImage.png"); //shows any masked regions not filled by image
+ --checkerboard : url('/assets/waterColorMasks/missingImage.png'); //shows any masked regions not filled by image
}
}
.imageMaskEdge {
- &1 { --wc : url("/assets/waterColorMasks/edge/0001.webp"); }
- &2 { --wc : url("/assets/waterColorMasks/edge/0002.webp"); }
- &3 { --wc : url("/assets/waterColorMasks/edge/0003.webp"); }
- &4 { --wc : url("/assets/waterColorMasks/edge/0004.webp"); }
- &5 { --wc : url("/assets/waterColorMasks/edge/0005.webp"); }
- &6 { --wc : url("/assets/waterColorMasks/edge/0006.webp"); }
- &7 { --wc : url("/assets/waterColorMasks/edge/0007.webp"); }
- &8 { --wc : url("/assets/waterColorMasks/edge/0008.webp"); }
+ &1 { --wc : url('/assets/waterColorMasks/edge/0001.webp'); }
+ &2 { --wc : url('/assets/waterColorMasks/edge/0002.webp'); }
+ &3 { --wc : url('/assets/waterColorMasks/edge/0003.webp'); }
+ &4 { --wc : url('/assets/waterColorMasks/edge/0004.webp'); }
+ &5 { --wc : url('/assets/waterColorMasks/edge/0005.webp'); }
+ &6 { --wc : url('/assets/waterColorMasks/edge/0006.webp'); }
+ &7 { --wc : url('/assets/waterColorMasks/edge/0007.webp'); }
+ &8 { --wc : url('/assets/waterColorMasks/edge/0008.webp'); }
}
[class*='imageMaskCenter'] {
@@ -296,15 +297,15 @@ body { counter-reset : page-numbers 0; }
left : calc(var(--offsetX));
width : 100%;
height : 100%;
- transform : rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY));
-webkit-mask-image : var(--wc), var(--revealer);
- -webkit-mask-repeat : no-repeat;
- -webkit-mask-size : 100% 100%; //Scale both dimensions to fit page size
- -webkit-mask-position : 0% 0%;
mask-image : var(--wc), var(--revealer);
+ -webkit-mask-repeat : no-repeat;
mask-repeat : no-repeat;
- mask-size : 100% 100%; //Scale both dimensions to fit page size
+ -webkit-mask-position : 0% 0%;
mask-position : 50% 50%;
+ -webkit-mask-size : 100% 100%; //Scale both dimensions to fit page size
+ mask-size : 100% 100%; //Scale both dimensions to fit page size
+ transform : rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY));
& > p:has(img) {
position : absolute;
@@ -321,23 +322,23 @@ body { counter-reset : page-numbers 0; }
}
.imageMaskCenter {
- &1 { --wc : url("/assets/waterColorMasks/center/0001.webp"); }
- &2 { --wc : url("/assets/waterColorMasks/center/0002.webp"); }
- &3 { --wc : url("/assets/waterColorMasks/center/0003.webp"); }
- &4 { --wc : url("/assets/waterColorMasks/center/0004.webp"); }
- &5 { --wc : url("/assets/waterColorMasks/center/0005.webp"); }
- &6 { --wc : url("/assets/waterColorMasks/center/0006.webp"); }
- &7 { --wc : url("/assets/waterColorMasks/center/0007.webp"); }
- &8 { --wc : url("/assets/waterColorMasks/center/0008.webp"); }
- &9 { --wc : url("/assets/waterColorMasks/center/0009.webp"); }
- &10 { --wc : url("/assets/waterColorMasks/center/0010.webp"); }
- &11 { --wc : url("/assets/waterColorMasks/center/0011.webp"); }
- &12 { --wc : url("/assets/waterColorMasks/center/0012.webp"); }
- &13 { --wc : url("/assets/waterColorMasks/center/0013.webp"); }
- &14 { --wc : url("/assets/waterColorMasks/center/0014.webp"); }
- &15 { --wc : url("/assets/waterColorMasks/center/0015.webp"); }
- &16 { --wc : url("/assets/waterColorMasks/center/0016.webp"); }
- &special { --wc : url("/assets/waterColorMasks/center/special.webp"); }
+ &1 { --wc : url('/assets/waterColorMasks/center/0001.webp'); }
+ &2 { --wc : url('/assets/waterColorMasks/center/0002.webp'); }
+ &3 { --wc : url('/assets/waterColorMasks/center/0003.webp'); }
+ &4 { --wc : url('/assets/waterColorMasks/center/0004.webp'); }
+ &5 { --wc : url('/assets/waterColorMasks/center/0005.webp'); }
+ &6 { --wc : url('/assets/waterColorMasks/center/0006.webp'); }
+ &7 { --wc : url('/assets/waterColorMasks/center/0007.webp'); }
+ &8 { --wc : url('/assets/waterColorMasks/center/0008.webp'); }
+ &9 { --wc : url('/assets/waterColorMasks/center/0009.webp'); }
+ &10 { --wc : url('/assets/waterColorMasks/center/0010.webp'); }
+ &11 { --wc : url('/assets/waterColorMasks/center/0011.webp'); }
+ &12 { --wc : url('/assets/waterColorMasks/center/0012.webp'); }
+ &13 { --wc : url('/assets/waterColorMasks/center/0013.webp'); }
+ &14 { --wc : url('/assets/waterColorMasks/center/0014.webp'); }
+ &15 { --wc : url('/assets/waterColorMasks/center/0015.webp'); }
+ &16 { --wc : url('/assets/waterColorMasks/center/0016.webp'); }
+ &special { --wc : url('/assets/waterColorMasks/center/special.webp'); }
}
@@ -346,15 +347,15 @@ body { counter-reset : page-numbers 0; }
left : calc(-50% + var(--offsetX));
width : 200%;
height : 200%;
- transform : rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY));
-webkit-mask-image : var(--wc), var(--revealer);
- -webkit-mask-repeat : no-repeat;
- -webkit-mask-size : 100% 100%; //Scale both dimensions to fit page size
- -webkit-mask-position : 50% 50%;
mask-image : var(--wc), var(--revealer);
+ -webkit-mask-repeat : no-repeat;
mask-repeat : no-repeat;
- mask-size : 100% 100%; //Scale both dimensions to fit page size
+ -webkit-mask-position : 50% 50%;
mask-position : 50% 50%;
+ -webkit-mask-size : 100% 100%; //Scale both dimensions to fit page size
+ mask-size : 100% 100%; //Scale both dimensions to fit page size
+ transform : rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY));
& > p:has(img) {
bottom : 25%;
left : 25%;
@@ -367,43 +368,43 @@ body { counter-reset : page-numbers 0; }
}
}
.imageMaskCorner {
- &1 { --wc : url("/assets/waterColorMasks/corner/0001.webp"); }
- &2 { --wc : url("/assets/waterColorMasks/corner/0002.webp"); }
- &3 { --wc : url("/assets/waterColorMasks/corner/0003.webp"); }
- &4 { --wc : url("/assets/waterColorMasks/corner/0004.webp"); }
- &5 { --wc : url("/assets/waterColorMasks/corner/0005.webp"); }
- &6 { --wc : url("/assets/waterColorMasks/corner/0006.webp"); }
- &7 { --wc : url("/assets/waterColorMasks/corner/0007.webp"); }
- &8 { --wc : url("/assets/waterColorMasks/corner/0008.webp"); }
- &9 { --wc : url("/assets/waterColorMasks/corner/0009.webp"); }
- &10 { --wc : url("/assets/waterColorMasks/corner/0010.webp"); }
- &11 { --wc : url("/assets/waterColorMasks/corner/0011.webp"); }
- &12 { --wc : url("/assets/waterColorMasks/corner/0012.webp"); }
- &13 { --wc : url("/assets/waterColorMasks/corner/0013.webp"); }
- &14 { --wc : url("/assets/waterColorMasks/corner/0014.webp"); }
- &15 { --wc : url("/assets/waterColorMasks/corner/0015.webp"); }
- &16 { --wc : url("/assets/waterColorMasks/corner/0016.webp"); }
- &17 { --wc : url("/assets/waterColorMasks/corner/0017.webp"); }
- &18 { --wc : url("/assets/waterColorMasks/corner/0018.webp"); }
- &19 { --wc : url("/assets/waterColorMasks/corner/0019.webp"); }
- &20 { --wc : url("/assets/waterColorMasks/corner/0020.webp"); }
- &21 { --wc : url("/assets/waterColorMasks/corner/0021.webp"); }
- &22 { --wc : url("/assets/waterColorMasks/corner/0022.webp"); }
- &23 { --wc : url("/assets/waterColorMasks/corner/0023.webp"); }
- &24 { --wc : url("/assets/waterColorMasks/corner/0024.webp"); }
- &25 { --wc : url("/assets/waterColorMasks/corner/0025.webp"); }
- &26 { --wc : url("/assets/waterColorMasks/corner/0026.webp"); }
- &27 { --wc : url("/assets/waterColorMasks/corner/0027.webp"); }
- &28 { --wc : url("/assets/waterColorMasks/corner/0028.webp"); }
- &29 { --wc : url("/assets/waterColorMasks/corner/0029.webp"); }
- &30 { --wc : url("/assets/waterColorMasks/corner/0030.webp"); }
- &31 { --wc : url("/assets/waterColorMasks/corner/0031.webp"); }
- &32 { --wc : url("/assets/waterColorMasks/corner/0032.webp"); }
- &33 { --wc : url("/assets/waterColorMasks/corner/0033.webp"); }
- &34 { --wc : url("/assets/waterColorMasks/corner/0034.webp"); }
- &35 { --wc : url("/assets/waterColorMasks/corner/0035.webp"); }
- &36 { --wc : url("/assets/waterColorMasks/corner/0036.webp"); }
- &37 { --wc : url("/assets/waterColorMasks/corner/0037.webp"); }
+ &1 { --wc : url('/assets/waterColorMasks/corner/0001.webp'); }
+ &2 { --wc : url('/assets/waterColorMasks/corner/0002.webp'); }
+ &3 { --wc : url('/assets/waterColorMasks/corner/0003.webp'); }
+ &4 { --wc : url('/assets/waterColorMasks/corner/0004.webp'); }
+ &5 { --wc : url('/assets/waterColorMasks/corner/0005.webp'); }
+ &6 { --wc : url('/assets/waterColorMasks/corner/0006.webp'); }
+ &7 { --wc : url('/assets/waterColorMasks/corner/0007.webp'); }
+ &8 { --wc : url('/assets/waterColorMasks/corner/0008.webp'); }
+ &9 { --wc : url('/assets/waterColorMasks/corner/0009.webp'); }
+ &10 { --wc : url('/assets/waterColorMasks/corner/0010.webp'); }
+ &11 { --wc : url('/assets/waterColorMasks/corner/0011.webp'); }
+ &12 { --wc : url('/assets/waterColorMasks/corner/0012.webp'); }
+ &13 { --wc : url('/assets/waterColorMasks/corner/0013.webp'); }
+ &14 { --wc : url('/assets/waterColorMasks/corner/0014.webp'); }
+ &15 { --wc : url('/assets/waterColorMasks/corner/0015.webp'); }
+ &16 { --wc : url('/assets/waterColorMasks/corner/0016.webp'); }
+ &17 { --wc : url('/assets/waterColorMasks/corner/0017.webp'); }
+ &18 { --wc : url('/assets/waterColorMasks/corner/0018.webp'); }
+ &19 { --wc : url('/assets/waterColorMasks/corner/0019.webp'); }
+ &20 { --wc : url('/assets/waterColorMasks/corner/0020.webp'); }
+ &21 { --wc : url('/assets/waterColorMasks/corner/0021.webp'); }
+ &22 { --wc : url('/assets/waterColorMasks/corner/0022.webp'); }
+ &23 { --wc : url('/assets/waterColorMasks/corner/0023.webp'); }
+ &24 { --wc : url('/assets/waterColorMasks/corner/0024.webp'); }
+ &25 { --wc : url('/assets/waterColorMasks/corner/0025.webp'); }
+ &26 { --wc : url('/assets/waterColorMasks/corner/0026.webp'); }
+ &27 { --wc : url('/assets/waterColorMasks/corner/0027.webp'); }
+ &28 { --wc : url('/assets/waterColorMasks/corner/0028.webp'); }
+ &29 { --wc : url('/assets/waterColorMasks/corner/0029.webp'); }
+ &30 { --wc : url('/assets/waterColorMasks/corner/0030.webp'); }
+ &31 { --wc : url('/assets/waterColorMasks/corner/0031.webp'); }
+ &32 { --wc : url('/assets/waterColorMasks/corner/0032.webp'); }
+ &33 { --wc : url('/assets/waterColorMasks/corner/0033.webp'); }
+ &34 { --wc : url('/assets/waterColorMasks/corner/0034.webp'); }
+ &35 { --wc : url('/assets/waterColorMasks/corner/0035.webp'); }
+ &36 { --wc : url('/assets/waterColorMasks/corner/0036.webp'); }
+ &37 { --wc : url('/assets/waterColorMasks/corner/0037.webp'); }
}
}
@@ -437,6 +438,11 @@ body { counter-reset : page-numbers 0; }
margin-bottom : 1em;
& + * { margin-top : 0; }
}
+ .blank {
+ height : 1em;
+ margin-top : 0;
+ & + * { margin-top : 0; }
+ }
}
//*****************************
@@ -461,8 +467,8 @@ body { counter-reset : page-numbers 0; }
height : 1.5cm;
margin : 0 auto;
background-color : black;
- -webkit-mask : url("/assets/naturalCritLogoWhite.svg") center / contain no-repeat;
- mask : url("/assets/naturalCritLogoWhite.svg") center / contain no-repeat;
+ -webkit-mask : url('/assets/naturalCritLogoWhite.svg') center / contain no-repeat;
+ mask : url('/assets/naturalCritLogoWhite.svg') center / contain no-repeat;
}
.homebreweryIcon.red { background-color : red; }
.homebreweryIcon.gold { background-image : linear-gradient(to top left, brown 22.5%, gold 40%, white 60%, gold 67.5%, brown 82.5%); }
@@ -486,12 +492,122 @@ body { counter-reset : page-numbers 0; }
.pageNumber { left : 30px; }
}
- .resetCounting {
- counter-set : page-numbers 1;
- }
+ .resetCounting { counter-set : page-numbers 1; }
- &:not(:has(.skipCounting)) {
- counter-increment : page-numbers;
- }
+ &:not(:has(.skipCounting)) { counter-increment : page-numbers; }
}
+
+// *****************************
+// * INDEX
+// *****************************/
+.page {
+ .index {
+
+ ul ul { margin : 0; }
+
+ ul {
+ padding-left : 0;
+ text-indent : 0;
+ list-style-type : none;
+ }
+
+ & > ul > li {
+ padding-left : 1.5em;
+ text-indent : -1.5em;
+ }
+ }
+}
+
+// *****************************
+// * TABLE OF CONTENTS
+// *****************************/
+
+// Default Exclusions
+// Anything not exlcuded is included, default Headers are H1, H2, and H3.
+h4,
+h5,
+h6,
+.page:has(.frontCover),
+.page:has(.backCover),
+.page:has(.insideCover),
+.noToC,
+.toc { --TOC : exclude; }
+
+.tocDepthH2 :is(h1, h2) {--TOC : include; }
+.tocDepthH3 :is(h1, h2, h3) {--TOC : include; }
+.tocDepthH4 :is(h1, h2, h3, h4) {--TOC : include; }
+.tocDepthH5 :is(h1, h2, h3, h4, h5) {--TOC : include; }
+.tocDepthH6 :is(h1, h2, h3, h4, h5, h6) {--TOC : include; }
+
+.tocIncludeH1 h1 {--TOC : include; }
+.tocIncludeH2 h2 {--TOC : include; }
+.tocIncludeH3 h3 {--TOC : include; }
+.tocIncludeH4 h4 {--TOC : include; }
+.tocIncludeH5 h5 {--TOC : include; }
+.tocIncludeH6 h6 {--TOC : include; }
+
+.page {
+ &:has(.toc)::after { display : none; }
+ .toc {
+ -webkit-column-break-inside : avoid;
+ page-break-inside : avoid;
+ break-inside : avoid;
+ h1 {
+ margin-bottom : 0.3cm;
+ text-align : center;
+ }
+ a {
+ display : inline;
+ color : inherit;
+ text-decoration : none;
+ &:hover { text-decoration : underline; }
+ }
+ h4 {
+ margin-top : 0.2cm;
+ line-height : 0.4cm;
+ & + ul li { line-height : 1.2em; }
+ }
+ ul {
+ padding-left : 0;
+ margin-top : 0;
+ list-style-type : none;
+ a {
+ display : flex;
+ flex-flow : row nowrap;
+ justify-content : space-between;
+ width : 100%;
+ }
+ li + li h3 {
+ margin-top : 0.26cm;
+ line-height : 1em;
+ }
+ h3 span:first-child::after { border : none; }
+ span {
+ display : contents;
+ &:first-child::after {
+ bottom : 0.08cm;
+ flex : 1;
+ margin-right : 0.16cm;
+ margin-bottom : 0.08cm;
+ margin-left : 0.08cm; /* Spacing before dot leaders */
+ content : '';
+ border-bottom : 0.05cm dotted #000000;
+ }
+ &:last-child {
+ display : inline-block;
+ align-self : flex-end;
+ font-size : 0.34cm;
+ font-weight : normal;
+ }
+ }
+ ul { /* List indent */
+ margin-left : 1em;
+ }
+ }
+ &.wide {
+ .useColumns(0.96, @fillMode: balance);
+ }
+ }
+ .toc.wide li { break-inside : auto; }
+}
diff --git a/themes/V3/Journal/snippets.js b/themes/V3/Journal/snippets.js
index 636befb60..bad5e8e6a 100644
--- a/themes/V3/Journal/snippets.js
+++ b/themes/V3/Journal/snippets.js
@@ -1,4 +1,4 @@
-/* eslint-disable max-lines */
+
module.exports = [
];
diff --git a/themes/V3/Journal/style.less b/themes/V3/Journal/style.less
index b8ed3ce8f..74c976f47 100644
--- a/themes/V3/Journal/style.less
+++ b/themes/V3/Journal/style.less
@@ -11,47 +11,35 @@
--HB_Color_WatercolorStain : #BBAD82; // Light brown
}
-.useSansSerif(){
- font-family : PermanentMarker;
+.useSansSerif() {
+ font-family : 'PermanentMarker';
font-size : 0.3cm;
line-height : 1.2em;
color : var(--HB_Color_Text2);
- p,dl,ul,ol {
- line-height : 1.2em;
- }
- ul, ol {
- padding-left : 1em;
- }
- em{
- font-style : italic;
- }
- strong{
- font-weight : 800;
+ p,dl,ul,ol { line-height : 1.2em; }
+ ul, ol { padding-left : 1em; }
+ em { font-style : italic; }
+ strong {
font-size : 1.1em;
+ font-weight : 800;
}
- h5 + * {
- margin-top : 0.1cm;
- }
-}
-.useColumns(@multiplier : 1, @fillMode: balance){
- column-gap : 0.5cm;
+ h5 + * { margin-top : 0.1cm; }
}
+.useColumns(@multiplier : 1, @fillMode: balance) { column-gap : 0.5cm; }
-.page{
- background-size : 200% 100%;
- background-repeat : no-repeat;
- filter : drop-shadow(1px 4px 14px black);
- background-image : url(/assets/Journal/Background1.webp);
+.page {
padding : 2.1cm 1.9cm 1.7cm 3.8cm;
- &:nth-of-type(2n + 1) {
- background-position : left;
- }
+ background-image : url('/assets/Journal/Background1.webp');
+ background-repeat : no-repeat;
+ background-size : 200% 100%;
+ filter : drop-shadow(1px 4px 14px black);
+ &:nth-of-type(2n + 1) { background-position : left; }
&:nth-of-type(2n) {
- background-position : right;
padding : 2.1cm 3.9cm 1.7cm 1.8cm;
+ background-position : right;
}
&:nth-of-type(2) {
- background-image : url(/assets/Journal/Background2.webp); //Only first page should show ribbon
+ background-image : url('/assets/Journal/Background2.webp'); //Only first page should show ribbon
}
& .columnWrapper {
@@ -59,167 +47,137 @@
}
}
- //*****************************
- // * BASE
+//*****************************
+// * BASE
// *****************************/
-.page{
- color : var(--HB_Color_Text);
- font-family : ReenieBeanie;
+.page {
+ font-family : 'ReenieBeanie';
font-size : 0.53cm;
line-height : 0.8em;
- p + * {
- margin-top : 0.325cm;
- }
- p + p{
- margin-top : 0;
- }
- ul{
- margin-bottom : 0.8em;
- }
- ol{
- margin-bottom : 0.8em;
- }
- em{
+ color : var(--HB_Color_Text);
+ p + * { margin-top : 0.325cm; }
+ p + p { margin-top : 0; }
+ ul { margin-bottom : 0.8em; }
+ ol { margin-bottom : 0.8em; }
+ em {
+ font-style : unset;
text-decoration : underline;
- font-style : unset;
- }
- del{
- text-decoration-style: double;
}
+ del { text-decoration-style : double; }
//Indents after p or lists
- p+p, ul+p, ol+p{
- text-indent : 1em;
- }
+ p + p, ul + p, ol + p { text-indent : 1em; }
//*****************************
// * HEADERS
// *****************************/
- h1,h2,h3,h4,h5{
- font-family : FrederickaTheGreat;
+ h1,h2,h3,h4,h5 {
+ font-family : 'FrederickaTheGreat';
font-weight : unset;
color : var(--HB_Color_HeaderText);
}
- h1{
+ h1 {
margin-bottom : 0.18cm; //Margin-bottom only because this is WIDE
font-size : 0.89cm;
- line-height : 1em;
font-variant : small-caps;
- &+p::first-letter{
+ line-height : 1em;
+ & + p::first-letter {
float : left;
- font-family : FrederickaTheGreat;
- line-height : 1em;
- font-size : 1.9em;
- padding-left : 40px; //Allow background color to extend into margins
- margin-top : -0.3cm;
- margin-bottom : -20px;
- margin-left : -40px;
- margin-right : 0.1em;
padding-top : 0.3em;
padding-bottom : 2px;
+ padding-left : 40px; //Allow background color to extend into margins
+ margin-top : -0.3cm;
+ margin-right : 0.1em;
+ margin-bottom : -20px;
+ margin-left : -40px;
+ font-family : 'FrederickaTheGreat';
+ font-size : 1.9em;
+ line-height : 1em;
}
- &+p::first-line{
- font-variant : small-caps;
- }
+ & + p::first-line { font-variant : small-caps; }
}
- h2{
+ h2 {
font-size : 0.62cm;
line-height : 0.988em; //Font is misaligned. Shift up slightly
}
- h3{
+ h3 {
+ margin-left : -0.9em;
font-size : 0.575cm;
line-height : 0.995em; //Font is misaligned. Shift up slightly
- margin-left : -0.9em;
}
- h4{
+ h4 {
+ padding-bottom : 5px;
font-size : 0.55cm;
line-height : 0.971em; //Font is misaligned. Shift up slightly
color : var(--HB_Color_Text);
- padding-bottom : 5px;
- transform:rotate(0deg);
- &:nth-of-type(2n) {
- transform:rotate(1deg);
- }
- &:nth-of-type(3n) {
- transform:rotate(-1.5deg);
- }
+ transform : rotate(0deg);
+ &:nth-of-type(2n) { transform : rotate(1deg); }
+ &:nth-of-type(3n) { transform : rotate(-1.5deg); }
}
- h5{
- font-family : PermanentMarker;
+ h5 {
+ font-family : 'PermanentMarker';
font-size : 0.4cm;
- color : var(--HB_Color_Text2);
font-weight : bold;
line-height : 0.951em; //Font is misaligned. Shift up slightly
- & + * {
- margin-top : 0.2cm;
- }
+ color : var(--HB_Color_Text2);
+ & + * { margin-top : 0.2cm; }
}
//*****************************
// * TABLE
// *****************************/
- table{
+ table {
.useSansSerif();
- & + * {
- margin-top : 0.325cm;
- }
- thead{
- th{
- vertical-align : bottom;
+ & + * { margin-top : 0.325cm; }
+ thead {
+ th {
padding : 0.14em 0;
+ vertical-align : bottom;
}
}
- tbody{
- tr{
- td{
- padding : 0.14em 0;
- }
- &:nth-child(odd){
- background-image : linear-gradient(to left, #41212100, #41212122, #41212100);
- }
+ tbody {
+ tr {
+ td { padding : 0.14em 0; }
+ &:nth-child(odd) { background-image : linear-gradient(to left, #41212100, #41212122, #41212100); }
}
}
}
//*****************************
// * NOTE
// *****************************/
- .note{
+ .note {
.useSansSerif();
+ padding : 0.2cm;
+ background-image : url('/assets/Journal/HashMarks.png'),
+ linear-gradient(to bottom right, #FF000000, #A36A4E14, #41212100);
+ background-repeat : no-repeat;
+ background-position : center;
+ background-size : 120% 120%;
border-style : solid;
border-width : 1px;
- border-image-source : url(/assets/Journal/Border1.png);
+ border-image-source : url('/assets/Journal/Border1.png');
border-image-slice : 18 18 18 18;
border-image-width : 6px 6px 6px 6px;
border-image-outset : 5px 5px 5px 5px;
border-image-repeat : stretch stretch;
- background-image : url(/assets/Journal/HashMarks.png),
- linear-gradient(to bottom right, #ff000000, #a36a4e14, #41212100);
- background-size : 120% 120%;
- background-repeat : no-repeat;
- background-position : center;
- padding : 0.2cm;
:where(&) {
margin-top : 9px; //Prevent top border getting cut off on colbreak
}
- & + * {
- margin-top : 0.45cm;
- }
- h5 {
- font-size : 0.375cm;
- }
- p{
- padding-bottom : 0px;
- }
- :last-child {
- margin-bottom : 0;
- }
+ & + * { margin-top : 0.45cm; }
+ h5 { font-size : 0.375cm; }
+ p { padding-bottom : 0px; }
+ :last-child { margin-bottom : 0; }
}
//************************************
// * DESCRIPTIVE TEXT BOX
// ************************************/
- * + .descriptive {
- margin-top : 0.6cm;
- }
- .descriptive{
+ * + .descriptive { margin-top : 0.6cm; }
+ .descriptive {
.useSansSerif();
+ padding : 0.2cm;
+ background-image : url('/assets/Journal/HashMarks.png'),
+ linear-gradient(to bottom right, #FF000000, #41212114, #41212100);
+ background-repeat : no-repeat;
+ background-position : center;
+ background-size : 120% 120%;
border-style : solid;
border-width : 1px;
border-image-source : url('/assets/Journal/Border2.png');
@@ -227,27 +185,13 @@
border-image-width : 20px;
border-image-outset : 16px 20px 16px 20px;
border-image-repeat : stretch stretch;
- background-image : url(/assets/Journal/HashMarks.png),
- linear-gradient(to bottom right, #ff000000, #41212114, #41212100);
- background-size : 120% 120%;
- background-repeat : no-repeat;
- background-position : center;
- padding : 0.2cm;
:where(&) {
margin-top : 4px; //Prevent top border getting cut off on colbreak
}
- & + * {
- margin-top : 0.45cm;
- }
- h5 {
- font-size : 0.375cm;
- }
- p{
- padding-bottom : 0px;
- }
- :last-child {
- margin-bottom : 0;
- }
+ & + * { margin-top : 0.45cm; }
+ h5 { font-size : 0.375cm; }
+ p { padding-bottom : 0px; }
+ :last-child { margin-bottom : 0; }
}
//*****************************
// * Images Snippets
@@ -257,25 +201,23 @@
.artist {
position : absolute;
width : auto;
- text-align : center;
- font-family : WalterTurncoat;
+ font-family : 'WalterTurncoat';
font-size : 0.27cm;
color : var(--HB_Color_CaptionText);
+ text-align : center;
p, p + p {
margin : unset;
- text-indent : unset;
line-height : 1em;
+ text-indent : unset;
}
- h5 {
+ h5 {
+ font-family : 'WalterTurncoat';
font-size : 1.3em;
- font-family : WalterTurncoat;
}
- a{
+ a {
color : inherit;
text-decoration : unset;
- &:hover {
- text-decoration : underline;
- }
+ &:hover { text-decoration : underline; }
}
}
@@ -285,6 +227,10 @@
.monster {
.useSansSerif();
&.frame {
+ padding : 0.2cm;
+ background-image : url('/assets/Journal/HashMarks.png'),
+ linear-gradient(to bottom right, #FF000000, #A36A4E14, #41212100);
+ background-size : 100%;
border-style : solid;
border-width : 7px 6px;
border-image-source : url('/assets/Journal/Border3.png');
@@ -292,33 +238,29 @@
border-image-width : 15px 20px 15px 20px;
border-image-outset : 12px 12px 12px 12px;
border-image-repeat : stretch round;
- background-image : url('/assets/Journal/HashMarks.png'),
- linear-gradient(to bottom right, #ff000000, #a36a4e14, #41212100);
background-blend-mode : screen multiply;
- background-size : 100%;
- padding : 0.2cm;
}
-
- color: var(--HB_Color_Text);
position : relative;
padding : 0px;
margin-bottom : 0.325cm;
+ color : var(--HB_Color_Text);
+
//Headers
- h2{
+ h2 {
+ margin : 0;
font-size : 0.62cm;
line-height : 1em;
- margin : 0;
- &+p {
+ & + p {
margin-bottom : 0; //Monster size and type subtext
}
}
- h3{
+ h3 {
+ padding-bottom : 0.05cm;
margin-left : 0;
font-variant : small-caps;
- padding-bottom : 0.05cm;
}
- hr{
+ hr {
visibility : visible;
height : 6px;
margin : 0.12cm 0cm;
@@ -330,24 +272,18 @@
}
// Monster Ability table
- hr + table:first-of-type{
+ hr + table:first-of-type {
margin : 0;
- column-span : none;
- background-image : none;
+ color : inherit;
+ background-image : none;
border-style : none;
border-image : none;
- color : inherit;
- tr {
- background-image : none;
- }
- td,th {
- padding: 0px;
- }
+ column-span : none;
+ tr { background-image : none; }
+ td,th { padding : 0px; }
}
- :last-child {
- margin-bottom : 0;
- }
+ :last-child { margin-bottom : 0; }
strong, em {
font-style : normal;
@@ -356,29 +292,27 @@
}
//Full Width
- .monster.wide{
+ .monster.wide {
.useColumns(0.96, @fillMode: balance);
}
//*****************************
// * FOOTER
// *****************************/
- &:nth-child(odd){
- .pageNumber{
- left : 3cm;
- }
- .footnote{
+ &:nth-child(odd) {
+ .pageNumber { left : 3cm; }
+ .footnote {
left : 4.5cm;
text-align : left;
}
}
- .pageNumber{
- font-family : FrederickaTheGreat;
+ .pageNumber {
right : 3cm;
bottom : 1.25cm;
+ font-family : 'FrederickaTheGreat';
color : var(--HB_Color_HeaderText);
}
- .footnote{
+ .footnote {
position : absolute;
right : 4.5cm;
bottom : 1.25cm;
@@ -391,154 +325,134 @@
//************************************
// * CODE BLOCKS
// ************************************/
- code{
- font-size : 0.3cm;
+ code {
padding : 0px 4px;
- color : var(--HB_Color_Text);
+ font-size : 0.3cm;
vertical-align : middle;
- background-color : #faf7ea;
+ color : var(--HB_Color_Text);
+ background-color : #FAF7EA;
border-radius : 4px;
}
- pre code{
+ pre code {
+ padding : 0.15cm;
+ margin-bottom : 2px;
border-style : solid;
border-width : 1px;
+ border-radius : 12px;
border-image : @codeBorderImage 26 stretch;
border-image-width : 10px;
border-image-outset : 2px;
- border-radius : 12px;
- margin-bottom : 2px;
- padding : 0.15cm;
.page :where(&) {
margin-top : 2px; //Prevent top border getting cut off on colbreak
}
- & + * {
- margin-top : 0.325cm;
- }
+ & + * { margin-top : 0.325cm; }
}
//*****************************
// * EXTRAS
// *****************************/
- hr{
+ hr {
visibility : hidden;
- border : none;
margin : 0px;
+ border : none;
}
//Text indent right after table
- table+p{
- text-indent : 1em;
- }
+ table + p { text-indent : 1em; }
a, a:visited, a:hover {
- color: var(--HB_Color_Text);
- transition:all 1s ease;
- }
- a:hover {
- color:red;
+ color : var(--HB_Color_Text);
+ transition : all 1s ease;
}
+ a:hover { color : red; }
}
//*****************************
// * SPELL LIST
// *****************************/
-.page .spellList{
+.page .spellList {
.useSansSerif();
- font-family : PermanentMarker;
+ font-family : 'PermanentMarker';
column-count : 2;
- ul+h5{
- margin-top : 15px;
- }
- ul{
- margin-bottom : 0.5em;
+ ul + h5 { margin-top : 15px; }
+ ul {
padding-left : 1em;
+ margin-bottom : 0.5em;
text-indent : -1em;
list-style-type : none;
+ break-inside : auto;
-webkit-column-break-inside : auto;
page-break-inside : auto;
- break-inside : auto;
- }
- &.wide{
- column-count : 4;
}
+ &.wide { column-count : 4; }
}
//*****************************
// * CLASS TABLE
// *****************************/
-.page .classTable{
- th[colspan]:not([rowspan]) {
- white-space : nowrap;
- }
- h5 + table{
- margin-top : 0.2cm;
- }
+.page .classTable {
+ th[colspan]:not([rowspan]) { white-space : nowrap; }
+ h5 + table { margin-top : 0.2cm; }
}
//*****************************
// * TABLE OF CONTENTS
// *****************************/
-.page .toc{
+.page .toc {
-webkit-column-break-inside : avoid;
page-break-inside : avoid;
break-inside : avoid;
h1 {
- text-align : center;
margin-bottom : 0.3cm;
+ text-align : center;
}
- a{
+ a {
display : inline;
color : inherit;
text-decoration : none;
- &:hover{
- text-decoration : underline;
- }
+ &:hover { text-decoration : underline; }
}
h4 {
margin-top : 0.2cm;
line-height : 0.4cm;
- & + ul li {
- line-height: 1.2em;
- }
+ & + ul li { line-height : 1.2em; }
}
- ul{
+ ul {
padding-left : 0;
list-style-type : none;
li + li h3 {
margin-top : 0.26cm;
- line-height : 1em
- }
- h3 span:first-child::after {
- border : none;
+ line-height : 1em;
}
+ h3 span:first-child::after { border : none; }
span {
display : table-cell;
&:first-child {
- position : relative;
- overflow : hidden;
+ position : relative;
+ overflow : hidden;
&::after {
- content : "";
position : absolute;
bottom : 0.08cm;
- margin-left : 0.06cm; /* Spacing before dot leaders */
width : 100%;
- border-bottom : 0.05cm dotted #000;
+ margin-left : 0.06cm; /* Spacing before dot leaders */
+ content : '';
+ border-bottom : 0.05cm dotted #000000;
}
}
&:last-child {
- font-family : ReenieBeanie;
- font-size : 0.34cm;
- font-weight : normal;
- color : black;
- text-align : right;
- vertical-align : bottom; /* Keep page number bottom-aligned */
width : 1%;
padding-left : 0.06cm; /* Spacing after dot leaders */
- /*white-space : nowrap; /* Uncomment if needed */
+ font-family : 'ReenieBeanie';
+ font-size : 0.34cm;
+ font-weight : normal;
+ vertical-align : bottom; /* Keep page number bottom-aligned */
+ color : black;
+ text-align : right;
+ /* white-space : nowrap; /* Uncomment if needed */
}
}
- ul { /*List indent*/
+ ul { /* List indent */
margin-left : 1em;
}
}
- &.wide{
+ &.wide {
.useColumns(0.96, @fillMode: balance);
}
}
@@ -546,6 +460,4 @@
//*****************************
// * WIDE
// *****************************/
-.page .wide {
- margin-bottom : 0.45cm;
-}
+.page .wide { margin-bottom : 0.45cm; }
diff --git a/themes/codeMirror/customEditorStyles.less b/themes/codeMirror/customEditorStyles.less
index 367eaec33..8c48c1b43 100644
--- a/themes/codeMirror/customEditorStyles.less
+++ b/themes/codeMirror/customEditorStyles.less
@@ -1,88 +1,83 @@
.editor .codeEditor .CodeMirror {
- // Themes with dark backgrounds
- &.cm-s-3024-night,
- &.cm-s-abbott,
- &.cm-s-abcdef,
- &.cm-s-ambiance,
- &.cm-s-ayu-dark,
- &.cm-s-ayu-mirage,
- &.cm-s-base16-dark,
- &.cm-s-bespin,
- &.cm-s-blackboard,
- &.cm-s-cobalt,
- &.cm-s-colorforth,
- &.cm-s-darcula,
- &.cm-s-dracula,
- &.cm-s-duotone-dark,
- &.cm-s-erlang-dark,
- &.cm-s-gruvbox-dark,
- &.cm-s-hopscotch,
- &.cm-s-icecoder,
- &.cm-s-isotope,
- &.cm-s-lesser-dark,
- &.cm-s-liquibyte,
- &.cm-s-lucario,
- &.cm-s-material,
- &.cm-s-material-darker,
- &.cm-s-material-ocean,
- &.cm-s-material-palenight,
- &.cm-s-mbo,
- &.cm-s-midnight,
- &.cm-s-monokai,
- &.cm-s-moxer,
- &.cm-s-night,
- &.cm-s-nord,
- &.cm-s-oceanic-next,
- &.cm-s-panda-syntax,
- &.cm-s-paraiso-dark,
- &.cm-s-pastel-on-dark,
- &.cm-s-railscasts,
- &.cm-s-rubyblue,
- &.cm-s-seti,
- &.cm-s-shadowfox,
- &.cm-s-the-matrix,
- &.cm-s-tomorrow-night-bright,
- &.cm-s-tomorrow-night-eighties,
- &.cm-s-twilight,
- &.cm-s-vibrant-ink,
- &.cm-s-xq-dark,
- &.cm-s-yonce,
- &.cm-s-zenburn
- {
- .CodeMirror-code {
- .block:not(.cm-comment) {
- color: magenta;
- }
- .columnSplit {
- color: black;
- background-color: rgba(35,153,153,0.5);
- }
- .pageLine {
- background-color: rgba(255,255,255,0.5);
- & ~ pre.CodeMirror-line {
- color: black;
- }
- }
- }
- }
- // Themes with light backgrounds
- &.cm-s-default,
- &.cm-s-3024-day,
- &.cm-s-ambiance-mobile,
- &.cm-s-base16-light,
- &.cm-s-duotone-light,
- &.cm-s-eclipse,
- &.cm-s-elegant,
- &.cm-s-juejin,
- &.cm-s-neat,
- &.cm-s-neo,
- &.cm-s-paraiso-lightm
- &.cm-s-solarized,
- &.cm-s-ssms,
- &.cm-s-ttcn,
- &.cm-s-xq-light,
- &.cm-s-yeti {
- // Future styling for themes with light backgrounds
- --dummyVar: 'currently unused';
- }
+ // Themes with dark backgrounds
+ &.cm-s-3024-night,
+ &.cm-s-abbott,
+ &.cm-s-abcdef,
+ &.cm-s-ambiance,
+ &.cm-s-ayu-dark,
+ &.cm-s-ayu-mirage,
+ &.cm-s-base16-dark,
+ &.cm-s-bespin,
+ &.cm-s-blackboard,
+ &.cm-s-cobalt,
+ &.cm-s-colorforth,
+ &.cm-s-darcula,
+ &.cm-s-dracula,
+ &.cm-s-duotone-dark,
+ &.cm-s-erlang-dark,
+ &.cm-s-gruvbox-dark,
+ &.cm-s-hopscotch,
+ &.cm-s-icecoder,
+ &.cm-s-isotope,
+ &.cm-s-lesser-dark,
+ &.cm-s-liquibyte,
+ &.cm-s-lucario,
+ &.cm-s-material,
+ &.cm-s-material-darker,
+ &.cm-s-material-ocean,
+ &.cm-s-material-palenight,
+ &.cm-s-mbo,
+ &.cm-s-midnight,
+ &.cm-s-monokai,
+ &.cm-s-moxer,
+ &.cm-s-night,
+ &.cm-s-nord,
+ &.cm-s-oceanic-next,
+ &.cm-s-panda-syntax,
+ &.cm-s-paraiso-dark,
+ &.cm-s-pastel-on-dark,
+ &.cm-s-railscasts,
+ &.cm-s-rubyblue,
+ &.cm-s-seti,
+ &.cm-s-shadowfox,
+ &.cm-s-the-matrix,
+ &.cm-s-tomorrow-night-bright,
+ &.cm-s-tomorrow-night-eighties,
+ &.cm-s-twilight,
+ &.cm-s-vibrant-ink,
+ &.cm-s-xq-dark,
+ &.cm-s-yonce,
+ &.cm-s-zenburn {
+ .CodeMirror-code {
+ .block:not(.cm-comment) { color : magenta; }
+ .columnSplit {
+ color : black;
+ background-color : rgba(35,153,153,0.5);
+ }
+ .pageLine {
+ background-color : rgba(255,255,255,0.5);
+ & ~ pre.CodeMirror-line { color : black; }
+ }
+ }
+ }
+ // Themes with light backgrounds
+ &.cm-s-default,
+ &.cm-s-3024-day,
+ &.cm-s-ambiance-mobile,
+ &.cm-s-base16-light,
+ &.cm-s-duotone-light,
+ &.cm-s-eclipse,
+ &.cm-s-elegant,
+ &.cm-s-juejin,
+ &.cm-s-neat,
+ &.cm-s-neo,
+ &.cm-s-paraiso-lightm
+ &.cm-s-solarized,
+ &.cm-s-ssms,
+ &.cm-s-ttcn,
+ &.cm-s-xq-light,
+ &.cm-s-yeti {
+ // Future styling for themes with light backgrounds
+ --dummyVar : 'currently unused';
+ }
}
diff --git a/themes/fonts/5e legacy/fonts.less b/themes/fonts/5e legacy/fonts.less
index d4c10c456..680e395ec 100644
--- a/themes/fonts/5e legacy/fonts.less
+++ b/themes/fonts/5e legacy/fonts.less
@@ -1,61 +1,61 @@
/* Main Font, serif */
@font-face {
- font-family: BookSanity;
- src: url('../../../fonts/5e legacy/Bookinsanity.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "BookSanity";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e legacy/Bookinsanity.woff2');
}
@font-face {
- font-family: BookSanity;
- src: url('../../../fonts/5e legacy/Bookinsanity Bold.woff2');
- font-weight: bold;
- font-style: normal;
+ font-family : "BookSanity";
+ font-style : normal;
+ font-weight : bold;
+ src : url('../../../fonts/5e legacy/Bookinsanity Bold.woff2');
}
@font-face {
- font-family: BookSanity;
- src: url('../../../fonts/5e legacy/Bookinsanity Italic.woff2');
- font-weight: normal;
- font-style: italic;
+ font-family : "BookSanity";
+ font-style : italic;
+ font-weight : normal;
+ src : url('../../../fonts/5e legacy/Bookinsanity Italic.woff2');
}
@font-face {
- font-family: BookSanity;
- src: url('../../../fonts/5e legacy/Bookinsanity Bold Italic.woff2');
- font-weight: bold;
- font-style: italic;
+ font-family : "BookSanity";
+ font-style : italic;
+ font-weight : bold;
+ src : url('../../../fonts/5e legacy/Bookinsanity Bold Italic.woff2');
}
/* Notes and Tables, sans-serif */
@font-face {
- font-family: ScalySans;
- src: url('../../../fonts/5e legacy/Scaly Sans.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "ScalySans";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e legacy/Scaly Sans.woff2');
}
@font-face {
- font-family: ScalySansSmallCaps;
- src: url('../../../fonts/5e legacy/Scaly Sans Caps.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "ScalySansSmallCaps";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e legacy/Scaly Sans Caps.woff2');
}
@font-face {
- font-family: WalterTurncoat;
- src: url('../../../fonts/5e legacy/WalterTurncoat-Regular.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "WalterTurncoat";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e legacy/WalterTurncoat-Regular.woff2');
}
/* Headers */
@font-face {
- font-family: MrJeeves;
- src: url('../../../fonts/5e legacy/Mr Eaves Small Caps.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "MrJeeves";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e legacy/Mr Eaves Small Caps.woff2');
}
/* Fancy Drop Cap */
@font-face {
- font-family: Solberry;
- src: url('../../../fonts/5e legacy/Solbera Imitation.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "Solberry";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e legacy/Solbera Imitation.woff2');
}
diff --git a/themes/fonts/5e/fonts.less b/themes/fonts/5e/fonts.less
index c028b06f9..eec5c418f 100644
--- a/themes/fonts/5e/fonts.less
+++ b/themes/fonts/5e/fonts.less
@@ -1,143 +1,143 @@
/* Main Font, serif */
@font-face {
- font-family: BookInsanityRemake;
- src: url('../../../fonts/5e/Bookinsanity.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "BookInsanityRemake";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e/Bookinsanity.woff2');
}
@font-face {
- font-family: BookInsanityRemake;
- src: url('../../../fonts/5e/Bookinsanity Bold.woff2');
- font-weight: bold;
- font-style: normal;
+ font-family : "BookInsanityRemake";
+ font-style : normal;
+ font-weight : bold;
+ src : url('../../../fonts/5e/Bookinsanity Bold.woff2');
}
@font-face {
- font-family: BookInsanityRemake;
- src: url('../../../fonts/5e/Bookinsanity Italic.woff2');
- font-weight: normal;
- font-style: italic;
+ font-family : "BookInsanityRemake";
+ font-style : italic;
+ font-weight : normal;
+ src : url('../../../fonts/5e/Bookinsanity Italic.woff2');
}
@font-face {
- font-family: BookInsanityRemake;
- src: url('../../../fonts/5e/Bookinsanity Bold Italic.woff2');
- font-weight: bold;
- font-style: italic;
+ font-family : "BookInsanityRemake";
+ font-style : italic;
+ font-weight : bold;
+ src : url('../../../fonts/5e/Bookinsanity Bold Italic.woff2');
}
/* Notes and Tables, sans-serif */
@font-face {
- font-family: ScalySansRemake;
- src: url('../../../fonts/5e/Scaly Sans.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "ScalySansRemake";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e/Scaly Sans.woff2');
}
@font-face {
- font-family: ScalySansRemake;
- src: url('../../../fonts/5e/Scaly Sans Bold.woff2');
- font-weight: bold;
- font-style: normal;
+ font-family : "ScalySansRemake";
+ font-style : normal;
+ font-weight : bold;
+ src : url('../../../fonts/5e/Scaly Sans Bold.woff2');
}
@font-face {
- font-family: ScalySansRemake;
- src: url('../../../fonts/5e/Scaly Sans Italic.woff2');
- font-weight: normal;
- font-style: italic;
+ font-family : "ScalySansRemake";
+ font-style : italic;
+ font-weight : normal;
+ src : url('../../../fonts/5e/Scaly Sans Italic.woff2');
}
@font-face {
- font-family: ScalySansRemake;
- src: url('../../../fonts/5e/Scaly Sans Bold Italic.woff2');
- font-weight: bold;
- font-style: italic;
+ font-family : "ScalySansRemake";
+ font-style : italic;
+ font-weight : bold;
+ src : url('../../../fonts/5e/Scaly Sans Bold Italic.woff2');
}
@font-face {
- font-family: ScalySansSmallCapsRemake;
- src: url('../../../fonts/5e/Scaly Sans Caps.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "ScalySansSmallCapsRemake";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e/Scaly Sans Caps.woff2');
}
@font-face {
- font-family: WalterTurncoat;
- src: url('../../../fonts/5e/WalterTurncoat-Regular.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "WalterTurncoat";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e/WalterTurncoat-Regular.woff2');
}
/* Headers */
@font-face {
- font-family: MrEavesRemake;
- src: url('../../../fonts/5e/Mr Eaves Small Caps.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "MrEavesRemake";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e/Mr Eaves Small Caps.woff2');
}
/* Fancy Drop Cap */
@font-face {
- font-family: SolberaImitationRemake; //Tweaked 5e version
- src: url('../../../fonts/5e/Solbera Imitation Tweak.woff2');
- font-weight: 100 1000;
- font-style: normal;
- font-style: italic;
+ font-family : "SolberaImitationRemake"; //Tweaked 5e version
+ font-style : normal;
+ font-style : italic;
+ font-weight : 100 1000;
+ src : url('../../../fonts/5e/Solbera Imitation Tweak.woff2');
}
/* Cover Page */
@font-face {
- font-family: NodestoCapsCondensed;
- src: url('../../../fonts/5e/Nodesto Caps Condensed.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "NodestoCapsCondensed";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e/Nodesto Caps Condensed.woff2');
}
@font-face {
- font-family: NodestoCapsCondensed;
- src: url('../../../fonts/5e/Nodesto Caps Condensed Bold.woff2');
- font-weight: bold;
- font-style: normal;
+ font-family : "NodestoCapsCondensed";
+ font-style : normal;
+ font-weight : bold;
+ src : url('../../../fonts/5e/Nodesto Caps Condensed Bold.woff2');
}
@font-face {
- font-family: NodestoCapsCondensed;
- src: url('../../../fonts/5e/Nodesto Caps Condensed Italic.woff2');
- font-weight: normal;
- font-style: italic;
+ font-family : "NodestoCapsCondensed";
+ font-style : italic;
+ font-weight : normal;
+ src : url('../../../fonts/5e/Nodesto Caps Condensed Italic.woff2');
}
@font-face {
- font-family: NodestoCapsCondensed;
- src: url('../../../fonts/5e/Nodesto Caps Condensed Bold Italic.woff2');
- font-weight: bold;
- font-style: italic;
+ font-family : "NodestoCapsCondensed";
+ font-style : italic;
+ font-weight : bold;
+ src : url('../../../fonts/5e/Nodesto Caps Condensed Bold Italic.woff2');
}
@font-face {
- font-family: NodestoCapsWide;
- src: url('../../../fonts/5e/Nodesto Caps Wide.woff2');
- font-weight: normal;
- font-style: normal
+ font-family : "NodestoCapsWide";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e/Nodesto Caps Wide.woff2');
}
@font-face {
- font-family: Overpass;
- src: url('../../../fonts/5e/Overpass Medium.woff2');
- font-weight: 500;
- font-style: normal;
+ font-family : "Overpass";
+ font-style : normal;
+ font-weight : 500;
+ src : url('../../../fonts/5e/Overpass Medium.woff2');
}
@font-face {
- font-family: Davek;
- src: url('../../../fonts/5e/Davek.woff2');
- font-weight: 500;
- font-style: normal;
+ font-family : "Davek";
+ font-style : normal;
+ font-weight : 500;
+ src : url('../../../fonts/5e/Davek.woff2');
}
@font-face {
- font-family: Iokharic;
- src: url('../../../fonts/5e/Iokharic.woff2');
- font-weight: 500;
- font-style: normal;
+ font-family : "Iokharic";
+ font-style : normal;
+ font-weight : 500;
+ src : url('../../../fonts/5e/Iokharic.woff2');
}
@font-face {
- font-family: Rellanic;
- src: url('../../../fonts/5e/Rellanic.woff2');
- font-weight: 500;
- font-style: normal;
+ font-family : "Rellanic";
+ font-style : normal;
+ font-weight : 500;
+ src : url('../../../fonts/5e/Rellanic.woff2');
}
diff --git a/themes/fonts/Blank/fonts.less b/themes/fonts/Blank/fonts.less
index 4a3d2d1e8..6558c84b4 100644
--- a/themes/fonts/Blank/fonts.less
+++ b/themes/fonts/Blank/fonts.less
@@ -18,29 +18,29 @@ License:
*/
@font-face {
- font-family: Pagella;
- src: url('../../../fonts/Blank/texgyrepagella-regular.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "Pagella";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/Blank/texgyrepagella-regular.woff2');
}
@font-face {
- font-family: Pagella;
- src: url('../../../fonts/Blank/texgyrepagella-bold.woff2');
- font-weight: bold;
- font-style: normal;
+ font-family : "Pagella";
+ font-style : normal;
+ font-weight : bold;
+ src : url('../../../fonts/Blank/texgyrepagella-bold.woff2');
}
@font-face {
- font-family: Pagella;
- src: url('../../../fonts/Blank/texgyrepagella-italic.woff2');
- font-weight: normal;
- font-style: italic;
+ font-family : "Pagella";
+ font-style : italic;
+ font-weight : normal;
+ src : url('../../../fonts/Blank/texgyrepagella-italic.woff2');
}
@font-face {
- font-family: Pagella;
- src: url('../../../fonts/Blank/texgyrepagella-bolditalic.woff2');
- font-weight: bold;
- font-style: italic;
+ font-family : "Pagella";
+ font-style : italic;
+ font-weight : bold;
+ src : url('../../../fonts/Blank/texgyrepagella-bolditalic.woff2');
}
diff --git a/themes/fonts/Journal/fonts.less b/themes/fonts/Journal/fonts.less
index 703b594ba..20190c651 100644
--- a/themes/fonts/Journal/fonts.less
+++ b/themes/fonts/Journal/fonts.less
@@ -1,58 +1,58 @@
/* Main Font, serif */
@font-face {
- font-family: ReenieBeanie;
- src: url('../../../fonts/Journal/ReenieBeanie-Regular.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "ReenieBeanie";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/Journal/ReenieBeanie-Regular.woff2');
}
/* Notes and Tables, sans-serif */
@font-face {
- font-family: PermanentMarker;
- src: url('../../../fonts/Journal/PermanentMarker-Regular.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "PermanentMarker";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/Journal/PermanentMarker-Regular.woff2');
}
@font-face {
- font-family: WalterTurncoat;
- src: url('../../../fonts/5e/WalterTurncoat-Regular.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "WalterTurncoat";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/5e/WalterTurncoat-Regular.woff2');
}
/* Headers */
@font-face {
- font-family: FrederickaTheGreat;
- src: url('../../../fonts/Journal/FrederickaTheGreat-Regular.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "FrederickaTheGreat";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../../../fonts/Journal/FrederickaTheGreat-Regular.woff2');
}
/* Cover Page */
@font-face {
- font-family: NodestoCapsCondensed;
- src: url('../fonts/5e/Nodesto Caps Condensed.woff2');
- font-weight: normal;
- font-style: normal;
+ font-family : "NodestoCapsCondensed";
+ font-style : normal;
+ font-weight : normal;
+ src : url('../fonts/5e/Nodesto Caps Condensed.woff2');
}
@font-face {
- font-family: NodestoCapsCondensed;
- src: url('../fonts/5e/Nodesto Caps Condensed Bold.woff2');
- font-weight: bold;
- font-style: normal;
+ font-family : "NodestoCapsCondensed";
+ font-style : normal;
+ font-weight : bold;
+ src : url('../fonts/5e/Nodesto Caps Condensed Bold.woff2');
}
@font-face {
- font-family: NodestoCapsCondensed;
- src: url('../fonts/5e/Nodesto Caps Condensed Italic.woff2');
- font-weight: normal;
- font-style: italic;
+ font-family : "NodestoCapsCondensed";
+ font-style : italic;
+ font-weight : normal;
+ src : url('../fonts/5e/Nodesto Caps Condensed Italic.woff2');
}
@font-face {
- font-family: NodestoCapsCondensed;
- src: url('../fonts/5e/Nodesto Caps Condensed Bold Italic.woff2');
- font-weight: bold;
- font-style: italic;
+ font-family : "NodestoCapsCondensed";
+ font-style : italic;
+ font-weight : bold;
+ src : url('../fonts/5e/Nodesto Caps Condensed Bold Italic.woff2');
}
diff --git a/themes/fonts/iconFonts/diceFont.less b/themes/fonts/iconFonts/diceFont.less
index ec80f132b..3b60093d0 100644
--- a/themes/fonts/iconFonts/diceFont.less
+++ b/themes/fonts/iconFonts/diceFont.less
@@ -13,8 +13,8 @@
font-weight : normal;
font-variant : normal;
line-height : 1;
- text-decoration : inherit;
text-transform : none;
+ text-decoration : inherit;
text-rendering : optimizeLegibility;
/* Better Font Rendering =========== */
diff --git a/themes/fonts/iconFonts/fontAwesome.js b/themes/fonts/iconFonts/fontAwesome.js
index f5f89e3aa..bf11a7c92 100644
--- a/themes/fonts/iconFonts/fontAwesome.js
+++ b/themes/fonts/iconFonts/fontAwesome.js
@@ -1,3 +1,5 @@
+/* eslint-disable max-lines */
+
const fontAwesome = {
// FONT-AWESOME SOLID
'fas_0' : 'fas fa-0',
diff --git a/themes/phb.depricated.less b/themes/phb.depricated.less
index 992dab35b..7cc574183 100644
--- a/themes/phb.depricated.less
+++ b/themes/phb.depricated.less
@@ -1,31 +1,31 @@
-.phb{
+.phb {
//Double hr for full width elements
- hr+hr+blockquote{
- column-span : all;
+ hr + hr + blockquote {
-webkit-column-span : all;
-moz-column-span : all;
+ column-span : all;
}
//*****************************
// * CLASS TABLE
// *****************************/
- hr+table{
+ hr+table {
+ padding-top : 10px;
margin-top : -5px;
margin-bottom : 50px;
- padding-top : 10px;
border-collapse : separate;
background-color : white;
border : initial;
border-style : solid;
+ border-image-source : @frameBorderImage;
+ border-image-slice : 150 200 150 200;
+ border-image-width : 47px;
border-image-outset : 37px 17px;
border-image-repeat : round;
- border-image-slice : 150 200 150 200;
- border-image-source : @frameBorderImage;
- border-image-width : 47px;
}
- h5+hr+table{
- column-span : all;
+ h5 + hr + table {
-webkit-column-span : all;
-moz-column-span : all;
+ column-span : all;
}
}
\ No newline at end of file