Routing for operators, Styling for main page

This commit is contained in:
Felix Kaspar 2024-08-12 19:10:11 +02:00
parent f7f6d40eee
commit 51e35ee0ee
12 changed files with 201 additions and 363 deletions

View File

@ -15,13 +15,11 @@
"@stirling-pdf/shared-operations": "^0.0.0",
"@tauri-apps/api": "^1.5.1",
"archiver": "^6.0.1",
"bootstrap": "^5.3.2",
"i18next": "^23.6.0",
"i18next-browser-languagedetector": "^7.1.0",
"path-browserify": "^1.0.1",
"pdfjs-dist": "^4.0.189",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
"react-dom": "^18.2.0",
"react-i18next": "^13.3.1",
"react-icons": "^4.11.0",

View File

@ -2,18 +2,16 @@ import { Suspense } from "react";
import { Routes, Route, Outlet } from "react-router-dom";
import Home from "./pages/Home";
import Dynamic from "./pages/Dynamic";
import Operators from "./pages/Operators";
import NoMatch from "./pages/NoMatch";
import NavBar from "./components/NavBar";
import "bootstrap/dist/css/bootstrap.min.css";
import { Container } from "react-bootstrap";
import { useTranslation, initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import i18next from "i18next";
import resourcesToBackend from "i18next-resources-to-backend";
import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
i18next.use(LanguageDetector).use(initReactI18next).use(resourcesToBackend((language: string, namespace: string) => import(`../../shared-operations/public/locales/${namespace}/${language}.json`)))
.init({
@ -27,8 +25,6 @@ i18next.use(LanguageDetector).use(initReactI18next).use(resourcesToBackend((lang
initImmediate: false // Makes loading blocking but sync
}); // TODO: use i18next.config.ts instead
import "./root.css";
export default function App() {
return (
@ -39,13 +35,21 @@ export default function App() {
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="dynamic" element={<Dynamic />} />
{/* Using path="*"" means "match anything", so this route
acts like a catch-all for URLs that we don't have explicit
routes for. */}
<Route path="*" element={<NoMatch />} />
</Route>
<Route path="/operators" element={<Layout />}>
<Route index element={<NoMatch />} />
{listOperatorNames().map((name) => {
return <Route key={name} path={name} element={<Operators/>} />;
})}
<Route path="*" element={<NoMatch />} />
</Route>
<Route path="/convert" element={<Layout />}>
{/* <Route path="file-to-pdf" element={<ToPdf />} /> */}
<Route path="*" element={<NoMatch />} />
@ -69,9 +73,7 @@ function Layout() {
{/* An <Outlet> renders whatever child route is currently active,
so you can think about this <Outlet> as a placeholder for
the child routes we defined above. */}
<Container fluid="sm" className="">
<Outlet/>
</Container>
<Outlet/>
</div>
);
}

View File

@ -1,16 +1,13 @@
import { Container } from "react-bootstrap";
import StirlingLogo from "../assets/favicon.svg";
import NavBarStyles from "./NavBar.module.css";
function NavBar() {
return (
<nav>
<Container>
<a className={NavBarStyles.navbar_brand} href="/">
<img className={NavBarStyles.main_icon} src={StirlingLogo} alt="icon"/>
<span className={NavBarStyles.icon_text}>Stirling PDF</span>
</a>
</Container>
<a className={NavBarStyles.navbar_brand} href="/">
<img className={NavBarStyles.main_icon} src={StirlingLogo} alt="icon"/>
<span className={NavBarStyles.icon_text}>Stirling PDF</span>
</a>
</nav>
);
}

View File

@ -0,0 +1,22 @@
.operator_card {
border: 1px solid var(--md-sys-color-surface-5);
border-radius: 1.75rem;
padding: 1.25rem;
display: flex;
flex-direction: column;
align-items: flex-start;
background: var(--md-sys-color-surface-5);
transition: transform 0.3s, border 0.3s;
transform-origin: center center;
outline: 0px solid transparent;
}
.operator_card h3 {
margin-top: 0;
}
.operator_card:hover {
cursor: pointer;
transform: scale(1.08);
box-shadow: var(--md-sys-elevation-2);
}

View File

@ -0,0 +1,33 @@
import { useEffect, useState } from 'react';
import { getSchemaByName } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
import styles from './OperatorCard.module.css';
interface OperatorCardProps {
/** The text to display inside the button */
operatorInternalName: string;
}
export function OperatorCard({ operatorInternalName }: OperatorCardProps) {
const [schema, setSchema] = useState<any>(undefined); // TODO: Type as joi type
useEffect(() => {
getSchemaByName(operatorInternalName).then(schema => {
if(schema) {
setSchema(schema.schema);
}
});
}, [operatorInternalName]);
return (
<a key={operatorInternalName} href={"/operators/" + operatorInternalName}>
<div>
</div>
<div className={styles.operator_card}>
<h3>{ schema?.describe().flags.label }</h3>
{ schema?.describe().flags.description }
</div>
</a>
);
}

View File

@ -10,22 +10,15 @@ interface BuildFieldsProps {
export function BuildFields({ schemaDescription, onSubmit }: BuildFieldsProps) {
console.log("Render Build Fields", schemaDescription);
const label = (schemaDescription?.flags as any)?.label
const description = (schemaDescription?.flags as any)?.description;
const values = (schemaDescription?.keys as any)?.values.keys as { [key: string]: Joi.Description};
return (
<div>
<h3>{label}</h3>
{description}
<hr />
<form onSubmit={(e) => { onSubmit(e); e.preventDefault(); }}>
{
values ? Object.keys(values).map((key) => {
return (<GenericField key={key} fieldName={key} joiDefinition={values[key]} />)
}) : undefined
}
<input type="submit" value="Submit" />
</form>
</div>
<form onSubmit={(e) => { onSubmit(e); e.preventDefault(); }}>
{
values ? Object.keys(values).map((key) => {
return (<GenericField key={key} fieldName={key} joiDefinition={values[key]} />)
}) : undefined
}
<input type="submit" value="Submit" />
</form>
);
}

View File

@ -1,7 +1,10 @@
import { Link } from "react-router-dom";
import { getOperatorByName, getSchemaByName, listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
import styles from './home.module.css';
import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
import { OperatorCard } from "../components/OperatorCard";
import styles from './Home.module.css';
function Home() {
const operators = listOperatorNames();
@ -20,13 +23,10 @@ function Home() {
<div className={styles.operator_container}>
{
operators.map((operator) => {
return (<a key={operator} href={"/operators/" + operator}><div className={styles.operator_card}>{operator}</div></a>)
return (<OperatorCard key={operator} operatorInternalName={operator}></OperatorCard>)
})
}
</div>
<Link to="/dynamic">Dynamic</Link>
</div>
);
}

View File

@ -1,13 +1,14 @@
import { Fragment } from "react";
import { Link } from "react-router-dom";
function NoMatch() {
return (
<div>
<Fragment>
<h2>The Page you are trying to access does not exist.</h2>
<p>
<Link to="/">Go back home...</Link>
</p>
</div>
</Fragment>
);
}

View File

@ -1,53 +1,52 @@
import { Link } from "react-router-dom";
import { Fragment } from "react";
import { Fragment, useEffect } from "react";
import { BaseSyntheticEvent, useRef, useState } from "react";
import { Operator, OperatorSchema } from "@stirling-pdf/shared-operations/src/functions";
import Joi from "@stirling-tools/joi";
import { BuildFields } from "../components/fields/BuildFields";
import { getOperatorByName, getSchemaByName, listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
import { getOperatorByName, getSchemaByName } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
import { PdfFile, RepresentationType } from "@stirling-pdf/shared-operations/src/wrappers/PdfFile";
import { Action } from "@stirling-pdf/shared-operations/declarations/Action";
import { useLocation } from 'react-router-dom'
function Dynamic() {
const [schemaDescription, setSchemaDescription] = useState<Joi.Description>();
const [schema, setSchema] = useState<any>(undefined); // TODO: Type as joi type
const operators = listOperatorNames();
const location = useLocation();
const activeOperatorName = useRef<string>();
const activeOperator = useRef<typeof Operator>();
const activeSchema = useRef<OperatorSchema>();
const operatorInternalName = location.pathname.split("/")[2]; // /operators/<operatorInternalName>
async function selectionChanged(s: BaseSyntheticEvent) {
const selectedValue = s.target.value;
console.log("Selection changed to", selectedValue);
if(selectedValue == "none") {
setSchemaDescription(undefined);
return;
}
getSchemaByName(selectedValue).then(async schema => {
useEffect(() => {
getSchemaByName(operatorInternalName).then(schema => {
if(schema) {
const description = schema.schema.describe();
activeOperatorName.current = selectedValue;
activeOperator.current = await getOperatorByName(selectedValue);
activeSchema.current = schema;
// This will update children
setSchemaDescription(description);
setSchema(schema.schema);
}
});
}
}, [location]);
return (
<Fragment>
<h3>{ schema?.describe().flags.label }</h3>
{ schema?.describe().flags.description }
<br />
<input type="file" id="pdfFile" accept=".pdf" multiple />
<br />
<div id="values">
<BuildFields schemaDescription={schema?.describe()} onSubmit={handleSubmit}></BuildFields>
</div>
</Fragment>
);
async function handleSubmit(e: BaseSyntheticEvent) {
console.clear();
if(!activeOperatorName.current || !activeOperator.current || !activeSchema.current) {
throw new Error("Please select an Operator in the Dropdown");
}
const formData = new FormData(e.target);
const values = Object.fromEntries(formData.entries());
let action: Action = {type: activeOperatorName.current, values: values};
let action: Action = {type: operatorInternalName, values: values};
// Validate PDF File
@ -71,14 +70,16 @@ function Dynamic() {
}
}
const validationResults = activeSchema.current.schema.validate({input: inputs, values: action.values});
const validationResults = schema.validate({input: inputs, values: action.values});
if(validationResults.error) {
console.error({error: "Validation failed", details: validationResults.error.message}, validationResults.error.stack);
}
else {
action.values = validationResults.value.values;
const operation = new activeOperator.current(action);
const Operator = (await getOperatorByName(operatorInternalName))!;
const operation = new Operator(action);
operation.run(validationResults.value.input, (progress) => {
console.log("OperationProgress: " + progress.operationProgress, "CurFileProgress: " + progress.curFileProgress);
}).then(async pdfFiles => {
@ -92,29 +93,6 @@ function Dynamic() {
});
}
};
return (
<Fragment>
<h2>Dynamic test page for operators</h2>
<input type="file" id="pdfFile" accept=".pdf" multiple />
<br />
<select id="pdfOptions" onChange={selectionChanged}>
<option value="none">none</option>
{ operators.map((operator) => {
return (<option key={operator} value={operator}>{operator}</option>)
}) }
</select>
<div id="values">
<BuildFields schemaDescription={schemaDescription} onSubmit={handleSubmit}></BuildFields>
</div>
<p>
<Link to="/">Go back home...</Link>
</p>
</Fragment>
);
}

View File

@ -2,17 +2,4 @@
display: grid;
grid-template-columns: repeat(auto-fill, minmax(15rem, 3fr));
gap: 30px 30px;
}
.operator_card {
border: 1px solid var(--md-sys-color-surface-5);
border-radius: 1.75rem;
padding: 1.25rem;
display: flex;
flex-direction: column;
align-items: flex-start;
background: var(--md-sys-color-surface-5);
transition: transform 0.3s, border 0.3s;
transform-origin: center center;
outline: 0px solid transparent;
}

View File

@ -1,34 +1,34 @@
:root {
--md-sys-color-primary: rgb(162 201 255);
--md-sys-color-surface-tint: rgb(162 201 255);
--md-sys-color-on-primary: rgb(0 49 92);
--md-sys-color-primary-container: rgb(0 118 208);
--md-sys-color-on-primary-container: rgb(255 255 255);
--md-sys-color-secondary: rgb(169 201 246);
--md-sys-color-on-secondary: rgb(12 49 87);
--md-sys-color-secondary-container: rgb(29 62 100);
--md-sys-color-on-secondary-container: rgb(180 210 255);
--md-sys-color-tertiary: rgb(193 194 248);
--md-sys-color-on-tertiary: rgb(42 44 88);
--md-sys-color-tertiary-container: rgb(110 112 161);
--md-sys-color-on-tertiary-container: rgb(255 255 255);
--md-sys-color-error: rgb(255 180 171);
--md-sys-color-on-error: rgb(105 0 5);
--md-sys-color-error-container: rgb(147 0 10);
--md-sys-color-on-error-container: rgb(255 218 214);
--md-sys-color-background: rgb(15 20 26);
--md-sys-color-on-background: rgb(223 226 235);
--md-sys-color-surface: rgb(15 20 26);
--md-sys-color-on-surface: rgb(223 226 235);
--md-sys-color-surface-variant: rgb(64 71 83);
--md-sys-color-on-surface-variant: rgb(192 199 213);
--md-sys-color-outline: rgb(138 145 158);
--md-sys-color-outline-variant: rgb(64 71 83);
--md-sys-color-primary: rgb(0 96 170);
--md-sys-color-surface-tint: rgb(0 96 170);
--md-sys-color-on-primary: rgb(255 255 255);
--md-sys-color-primary-container: rgb(80 163 255);
--md-sys-color-on-primary-container: rgb(0 20 43);
--md-sys-color-secondary: rgb(65 96 136);
--md-sys-color-on-secondary: rgb(255 255 255);
--md-sys-color-secondary-container: rgb(188 215 255);
--md-sys-color-on-secondary-container: rgb(32 65 103);
--md-sys-color-tertiary: rgb(88 90 138);
--md-sys-color-on-tertiary: rgb(255 255 255);
--md-sys-color-tertiary-container: rgb(151 153 205);
--md-sys-color-on-tertiary-container: rgb(7 9 55);
--md-sys-color-error: rgb(186 26 26);
--md-sys-color-on-error: rgb(255 255 255);
--md-sys-color-error-container: rgb(255 218 214);
--md-sys-color-on-error-container: rgb(65 0 2);
--md-sys-color-background: rgb(248 249 255);
--md-sys-color-on-background: rgb(24 28 34);
--md-sys-color-surface: rgb(248 249 255);
--md-sys-color-on-surface: rgb(24 28 34);
--md-sys-color-surface-variant: rgb(220 227 241);
--md-sys-color-on-surface-variant: rgb(64 71 83);
--md-sys-color-outline: rgb(112 119 132);
--md-sys-color-outline-variant: rgb(192 199 213);
--md-sys-color-shadow: rgb(0 0 0);
--md-sys-color-scrim: rgb(0 0 0);
--md-sys-color-inverse-surface: rgb(223 226 235);
--md-sys-color-inverse-on-surface: rgb(45 49 55);
--md-sys-color-inverse-primary: rgb(0 96 170);
--md-sys-color-inverse-surface: rgb(45 49 55);
--md-sys-color-inverse-on-surface: rgb(238 241 250);
--md-sys-color-inverse-primary: rgb(162 201 255);
--md-sys-color-primary-fixed: rgb(211 228 255);
--md-sys-color-on-primary-fixed: rgb(0 28 56);
--md-sys-color-primary-fixed-dim: rgb(162 201 255);
@ -41,33 +41,58 @@
--md-sys-color-on-tertiary-fixed: rgb(20 22 66);
--md-sys-color-tertiary-fixed-dim: rgb(193 194 248);
--md-sys-color-on-tertiary-fixed-variant: rgb(64 67 112);
--md-sys-color-surface-dim: rgb(15 20 26);
--md-sys-color-surface-bright: rgb(53 57 64);
--md-sys-color-surface-container-lowest: rgb(10 14 20);
--md-sys-color-surface-container-low: rgb(24 28 34);
--md-sys-color-surface-container: rgb(28 32 38);
--md-sys-color-surface-container-high: rgb(38 42 49);
--md-sys-color-surface-container-highest: rgb(49 53 60);
--md-sys-color-surface-dim: rgb(215 218 227);
--md-sys-color-surface-bright: rgb(248 249 255);
--md-sys-color-surface-container-lowest: rgb(255 255 255);
--md-sys-color-surface-container-low: rgb(241 243 253);
--md-sys-color-surface-container: rgb(235 238 247);
--md-sys-color-surface-container-high: rgb(229 232 241);
--md-sys-color-surface-container-highest: rgb(223 226 235);
--md-nav-section-color-opacity: 1;
--md-nav-on-section-color-opacity: 1;
--md-nav-section-color-sign: rgba(25, 101, 212, var(--md-nav-section-color-opacity));
--md-nav-on-section-color-sign: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
--md-nav-on-section-color-sign: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
--md-nav-section-color-organize: rgba(120, 130, 255, var(--md-nav-section-color-opacity));
--md-nav-on-section-color-organize: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
--md-nav-on-section-color-organize: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
--md-nav-section-color-convert: rgba(25, 177, 212, var(--md-nav-section-color-opacity));
--md-nav-on-section-color-convert: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
--md-nav-on-section-color-convert: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
--md-nav-section-color-security: rgba(255, 120, 146, var(--md-nav-section-color-opacity));
--md-nav-on-section-color-security: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
--md-nav-on-section-color-security: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
--md-nav-section-color-other: rgba(72, 189, 84, var(--md-nav-section-color-opacity));
--md-nav-on-section-color-other: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
--md-nav-on-section-color-other: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
--md-nav-section-color-advance: rgba(245, 84, 84, var(--md-nav-section-color-opacity));
--md-nav-on-section-color-advance: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
--md-nav-on-section-color-advance: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
--md-nav-section-color-image: rgba(212, 172, 25, var(--md-nav-section-color-opacity));
--md-nav-on-section-color-image: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
--md-nav-on-section-color-image: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
--md-nav-section-color-word: rgba(61, 153, 245, var(--md-nav-section-color-opacity));
--md-nav-on-section-color-word: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
--md-nav-on-section-color-word: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
--md-nav-section-color-ppt: rgba(255, 128, 0, var(--md-nav-section-color-opacity));
--md-nav-on-section-color-ppt: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
--md-nav-on-section-color-ppt: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
--bs-blue: #0d6efd;
--bs-indigo: #6610f2;
--bs-purple: #6f42c1;
--bs-pink: #d63384;
--bs-red: #dc3545;
--bs-orange: #fd7e14;
--bs-yellow: #ffc107;
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
--bs-light: #f8f9fa;
--bs-dark: #212529;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
}
:where(html, .light-theme, .dark-theme), .tokens, :host {
@ -100,8 +125,10 @@ body, select, textarea {
background-color: var(--md-sys-color-surface);
color: var(--md-sys-color-on-surface);
}
body {
margin: 0;
margin: 10px auto;
padding: 0 20px;
font-family: var(--bs-font-sans-serif);
font-size: 1rem;
font-weight: 400;
@ -110,4 +137,11 @@ body {
background-color: #fff;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: transparent;
max-width: 90%;
}
a {
text-decoration: inherit;
color: inherit;
}

209
package-lock.json generated
View File

@ -27,13 +27,11 @@
"@stirling-pdf/shared-operations": "^0.0.0",
"@tauri-apps/api": "^1.5.1",
"archiver": "^6.0.1",
"bootstrap": "^5.3.2",
"i18next": "^23.6.0",
"i18next-browser-languagedetector": "^7.1.0",
"path-browserify": "^1.0.1",
"pdfjs-dist": "^4.0.189",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
"react-dom": "^18.2.0",
"react-i18next": "^13.3.1",
"react-icons": "^4.11.0",
@ -1598,29 +1596,6 @@
"node": ">=14"
}
},
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@react-aria/ssr": {
"version": "3.9.1",
"resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.1.tgz",
"integrity": "sha512-NqzkLFP8ZVI4GSorS0AYljC13QW2sc8bDqJOkBvkAt3M8gbcAXJWVRGtZBCRscki9RZF+rNlnPdg0G0jYkhJcg==",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"engines": {
"node": ">= 12"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
}
},
"node_modules/@remix-run/router": {
"version": "1.14.2",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz",
@ -1629,45 +1604,6 @@
"node": ">=14.0.0"
}
},
"node_modules/@restart/hooks": {
"version": "0.4.15",
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.15.tgz",
"integrity": "sha512-cZFXYTxbpzYcieq/mBwSyXgqnGMHoBVh3J7MU0CCoIB4NRZxV9/TuwTBAaLMqpNhC3zTPMCgkQ5Ey07L02Xmcw==",
"dependencies": {
"dequal": "^2.0.3"
},
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@restart/ui": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz",
"integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==",
"dependencies": {
"@babel/runtime": "^7.21.0",
"@popperjs/core": "^2.11.6",
"@react-aria/ssr": "^3.5.0",
"@restart/hooks": "^0.4.9",
"@types/warning": "^3.0.0",
"dequal": "^2.0.3",
"dom-helpers": "^5.2.0",
"uncontrollable": "^8.0.1",
"warning": "^4.0.3"
},
"peerDependencies": {
"react": ">=16.14.0",
"react-dom": ">=16.14.0"
}
},
"node_modules/@restart/ui/node_modules/uncontrollable": {
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz",
"integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==",
"peerDependencies": {
"react": ">=16.14.0"
}
},
"node_modules/@rollup/plugin-alias": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz",
@ -2381,6 +2317,7 @@
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
"integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==",
"peer": true,
"dependencies": {
"tslib": "^2.4.0"
}
@ -2890,14 +2827,6 @@
"@types/react": "*"
}
},
"node_modules/@types/react-transition-group": {
"version": "4.4.10",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz",
"integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==",
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/readdir-glob": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.5.tgz",
@ -2959,11 +2888,6 @@
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.10.tgz",
"integrity": "sha512-e2PNXoXLr6Z+dbfx5zSh9TRlXJrELycxiaXznp4S5+D2M3b9bqJEitNHA5923jhnB2zzFiZHa2f0SI1HoIahpg=="
},
"node_modules/@types/warning": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz",
"integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q=="
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.18.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz",
@ -3570,24 +3494,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/bootstrap": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz",
"integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"peerDependencies": {
"@popperjs/core": "^2.11.8"
}
},
"node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@ -4062,11 +3968,6 @@
"safe-buffer": "^5.0.1"
}
},
"node_modules/classnames": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
},
"node_modules/clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@ -4687,14 +4588,6 @@
"node": ">= 0.8"
}
},
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
"engines": {
"node": ">=6"
}
},
"node_modules/des.js": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
@ -4773,15 +4666,6 @@
"node": ">=6.0.0"
}
},
"node_modules/dom-helpers": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
"dependencies": {
"@babel/runtime": "^7.8.7",
"csstype": "^3.0.2"
}
},
"node_modules/domain-browser": {
"version": "4.23.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz",
@ -6346,14 +6230,6 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"node_modules/invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/iobuffer": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.3.2.tgz",
@ -8562,18 +8438,6 @@
"react-is": "^16.13.1"
}
},
"node_modules/prop-types-extra": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
"integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
"dependencies": {
"react-is": "^16.3.2",
"warning": "^4.0.0"
},
"peerDependencies": {
"react": ">=0.14.0"
}
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -8748,35 +8612,6 @@
"node": ">=0.10.0"
}
},
"node_modules/react-bootstrap": {
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.2.tgz",
"integrity": "sha512-a36B+EHsAI/aH+ZhXNILBFnqscE3zr10dWmjBmfhIb2QR7KSXJiGzYd6Faf/25G8G7/CP9TCL2B0WhUBOD2UBQ==",
"dependencies": {
"@babel/runtime": "^7.22.5",
"@restart/hooks": "^0.4.9",
"@restart/ui": "^1.6.6",
"@types/react-transition-group": "^4.4.6",
"classnames": "^2.3.2",
"dom-helpers": "^5.2.1",
"invariant": "^2.2.4",
"prop-types": "^15.8.1",
"prop-types-extra": "^1.1.0",
"react-transition-group": "^4.4.5",
"uncontrollable": "^7.2.1",
"warning": "^4.0.3"
},
"peerDependencies": {
"@types/react": ">=16.14.8",
"react": ">=16.14.0",
"react-dom": ">=16.14.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
@ -8824,11 +8659,6 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"node_modules/react-refresh": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
@ -8880,21 +8710,6 @@
"react-dom": ">=16.8"
}
},
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
"dependencies": {
"@babel/runtime": "^7.5.5",
"dom-helpers": "^5.0.1",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2"
},
"peerDependencies": {
"react": ">=16.6.0",
"react-dom": ">=16.6.0"
}
},
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@ -10391,20 +10206,6 @@
"node": ">= 0.8"
}
},
"node_modules/uncontrollable": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",
"integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==",
"dependencies": {
"@babel/runtime": "^7.6.3",
"@types/react": ">=16.9.11",
"invariant": "^2.2.4",
"react-lifecycles-compat": "^3.0.4"
},
"peerDependencies": {
"react": ">=15.0.0"
}
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
@ -11154,14 +10955,6 @@
"node": ">=0.10.0"
}
},
"node_modules/warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",