Index: frontend/node_modules/@sinclair/typebox/compiler/compiler.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/compiler/compiler.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/compiler/compiler.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,28 @@
+import { ValueError } from '../errors/index';
+import * as Types from '../typebox';
+export declare type CheckFunction = (value: unknown) => boolean;
+export declare class TypeCheck<T extends Types.TSchema> {
+    private readonly schema;
+    private readonly references;
+    private readonly checkFunc;
+    private readonly code;
+    constructor(schema: T, references: Types.TSchema[], checkFunc: CheckFunction, code: string);
+    /** Returns the generated validation code used to validate this type. */
+    Code(): string;
+    /** Returns an iterator for each error in this value. */
+    Errors(value: unknown): IterableIterator<ValueError>;
+    /** Returns true if the value matches the given type. */
+    Check(value: unknown): value is Types.Static<T>;
+}
+export declare namespace Property {
+    function Check(propertyName: string): boolean;
+}
+export declare class TypeCompilerUnknownTypeError extends Error {
+    readonly schema: Types.TSchema;
+    constructor(schema: Types.TSchema);
+}
+/** Compiles Types for Runtime Type Checking */
+export declare namespace TypeCompiler {
+    /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
+    function Compile<T extends Types.TSchema>(schema: T, references?: Types.TSchema[]): TypeCheck<T>;
+}
Index: frontend/node_modules/@sinclair/typebox/compiler/compiler.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/compiler/compiler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/compiler/compiler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,409 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/compiler
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TypeCompiler = exports.TypeCompilerUnknownTypeError = exports.Property = exports.TypeCheck = void 0;
+const index_1 = require("../errors/index");
+const index_2 = require("../guard/index");
+const index_3 = require("../format/index");
+const Types = require("../typebox");
+// -------------------------------------------------------------------
+// TypeCheck
+// -------------------------------------------------------------------
+class TypeCheck {
+    constructor(schema, references, checkFunc, code) {
+        this.schema = schema;
+        this.references = references;
+        this.checkFunc = checkFunc;
+        this.code = code;
+    }
+    /** Returns the generated validation code used to validate this type. */
+    Code() {
+        return this.code;
+    }
+    /** Returns an iterator for each error in this value. */
+    Errors(value) {
+        return index_1.ValueErrors.Errors(this.schema, this.references, value);
+    }
+    /** Returns true if the value matches the given type. */
+    Check(value) {
+        return this.checkFunc(value);
+    }
+}
+exports.TypeCheck = TypeCheck;
+// -------------------------------------------------------------------
+// Property
+// -------------------------------------------------------------------
+var Property;
+(function (Property) {
+    function DollarSign(code) {
+        return code === 36;
+    }
+    function Underscore(code) {
+        return code === 95;
+    }
+    function Numeric(code) {
+        return code >= 48 && code <= 57;
+    }
+    function Alpha(code) {
+        return (code >= 65 && code <= 90) || (code >= 97 && code <= 122);
+    }
+    function Check(propertyName) {
+        if (propertyName.length === 0)
+            return false;
+        {
+            const code = propertyName.charCodeAt(0);
+            if (!(DollarSign(code) || Underscore(code) || Alpha(code))) {
+                return false;
+            }
+        }
+        for (let i = 1; i < propertyName.length; i++) {
+            const code = propertyName.charCodeAt(i);
+            if (!(DollarSign(code) || Underscore(code) || Alpha(code) || Numeric(code))) {
+                return false;
+            }
+        }
+        return true;
+    }
+    Property.Check = Check;
+})(Property = exports.Property || (exports.Property = {}));
+// -------------------------------------------------------------------
+// TypeCompiler
+// -------------------------------------------------------------------
+class TypeCompilerUnknownTypeError extends Error {
+    constructor(schema) {
+        super('TypeCompiler: Unknown type');
+        this.schema = schema;
+    }
+}
+exports.TypeCompilerUnknownTypeError = TypeCompilerUnknownTypeError;
+/** Compiles Types for Runtime Type Checking */
+var TypeCompiler;
+(function (TypeCompiler) {
+    // -------------------------------------------------------------------
+    // Types
+    // -------------------------------------------------------------------
+    function* Any(schema, value) {
+        yield '(true)';
+    }
+    function* Array(schema, value) {
+        const expression = CreateExpression(schema.items, 'value');
+        if (schema.minItems !== undefined)
+            yield `(${value}.length >= ${schema.minItems})`;
+        if (schema.maxItems !== undefined)
+            yield `(${value}.length <= ${schema.maxItems})`;
+        if (schema.uniqueItems !== undefined)
+            yield `(new Set(${value}).size === ${value}.length)`;
+        yield `(Array.isArray(${value}) && ${value}.every(value => ${expression}))`;
+    }
+    function* Boolean(schema, value) {
+        yield `(typeof ${value} === 'boolean')`;
+    }
+    function* Constructor(schema, value) {
+        yield* Visit(schema.returns, `${value}.prototype`);
+    }
+    function* Function(schema, value) {
+        yield `(typeof ${value} === 'function')`;
+    }
+    function* Integer(schema, value) {
+        yield `(typeof ${value} === 'number' && Number.isInteger(${value}))`;
+        if (schema.multipleOf !== undefined)
+            yield `(${value} % ${schema.multipleOf} === 0)`;
+        if (schema.exclusiveMinimum !== undefined)
+            yield `(${value} > ${schema.exclusiveMinimum})`;
+        if (schema.exclusiveMaximum !== undefined)
+            yield `(${value} < ${schema.exclusiveMaximum})`;
+        if (schema.minimum !== undefined)
+            yield `(${value} >= ${schema.minimum})`;
+        if (schema.maximum !== undefined)
+            yield `(${value} <= ${schema.maximum})`;
+    }
+    function* Literal(schema, value) {
+        if (typeof schema.const === 'number' || typeof schema.const === 'boolean') {
+            yield `(${value} === ${schema.const})`;
+        }
+        else {
+            yield `(${value} === '${schema.const}')`;
+        }
+    }
+    function* Never(schema, value) {
+        yield `(false)`;
+    }
+    function* Null(schema, value) {
+        yield `(${value} === null)`;
+    }
+    function* Number(schema, value) {
+        yield `(typeof ${value} === 'number')`;
+        if (schema.multipleOf !== undefined)
+            yield `(${value} % ${schema.multipleOf} === 0)`;
+        if (schema.exclusiveMinimum !== undefined)
+            yield `(${value} > ${schema.exclusiveMinimum})`;
+        if (schema.exclusiveMaximum !== undefined)
+            yield `(${value} < ${schema.exclusiveMaximum})`;
+        if (schema.minimum !== undefined)
+            yield `(${value} >= ${schema.minimum})`;
+        if (schema.maximum !== undefined)
+            yield `(${value} <= ${schema.maximum})`;
+    }
+    function* Object(schema, value) {
+        yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`;
+        if (schema.minProperties !== undefined)
+            yield `(Object.keys(${value}).length >= ${schema.minProperties})`;
+        if (schema.maxProperties !== undefined)
+            yield `(Object.keys(${value}).length <= ${schema.maxProperties})`;
+        const propertyKeys = globalThis.Object.keys(schema.properties);
+        if (schema.additionalProperties === false) {
+            // Optimization: If the property key length matches the required keys length
+            // then we only need check that the values property key length matches that
+            // of the property key length. This is because exhaustive testing for values
+            // will occur in subsequent property tests.
+            if (schema.required && schema.required.length === propertyKeys.length) {
+                yield `(Object.keys(${value}).length === ${propertyKeys.length})`;
+            }
+            else {
+                const keys = `[${propertyKeys.map((key) => `'${key}'`).join(', ')}]`;
+                yield `(Object.keys(${value}).every(key => ${keys}.includes(key)))`;
+            }
+        }
+        if (index_2.TypeGuard.TSchema(schema.additionalProperties)) {
+            const expression = CreateExpression(schema.additionalProperties, 'value[key]');
+            const keys = `[${propertyKeys.map((key) => `'${key}'`).join(', ')}]`;
+            yield `(Object.keys(${value}).every(key => ${keys}.includes(key) || ${expression}))`;
+        }
+        for (const propertyKey of propertyKeys) {
+            const memberExpression = Property.Check(propertyKey) ? `${value}.${propertyKey}` : `${value}['${propertyKey}']`;
+            const propertySchema = schema.properties[propertyKey];
+            if (schema.required && schema.required.includes(propertyKey)) {
+                yield* Visit(propertySchema, memberExpression);
+            }
+            else {
+                const expression = CreateExpression(propertySchema, memberExpression);
+                yield `(${memberExpression} === undefined ? true : (${expression}))`;
+            }
+        }
+    }
+    function* Promise(schema, value) {
+        yield `(typeof value === 'object' && typeof ${value}.then === 'function')`;
+    }
+    function* Record(schema, value) {
+        yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`;
+        const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
+        const local = PushLocal(`new RegExp(/${keyPattern}/)`);
+        yield `(Object.keys(${value}).every(key => ${local}.test(key)))`;
+        const expression = CreateExpression(valueSchema, 'value');
+        yield `(Object.values(${value}).every(value => ${expression}))`;
+    }
+    function* Ref(schema, value) {
+        // Reference: If we have seen this reference before we can just yield and return
+        // the function call. If this isn't the case we defer to visit to generate and
+        // set the function for subsequent passes. Consider for refactor.
+        if (names.has(schema.$ref))
+            return yield `(${CreateFunctionName(schema.$ref)}(${value}))`;
+        if (!referenceMap.has(schema.$ref))
+            throw Error(`TypeCompiler.Ref: Cannot de-reference schema with $id '${schema.$ref}'`);
+        const reference = referenceMap.get(schema.$ref);
+        yield* Visit(reference, value);
+    }
+    function* Self(schema, value) {
+        const func = CreateFunctionName(schema.$ref);
+        yield `(${func}(${value}))`;
+    }
+    function* String(schema, value) {
+        yield `(typeof ${value} === 'string')`;
+        if (schema.minLength !== undefined) {
+            yield `(${value}.length >= ${schema.minLength})`;
+        }
+        if (schema.maxLength !== undefined) {
+            yield `(${value}.length <= ${schema.maxLength})`;
+        }
+        if (schema.pattern !== undefined) {
+            const local = PushLocal(`new RegExp(/${schema.pattern}/);`);
+            yield `(${local}.test(${value}))`;
+        }
+        if (schema.format !== undefined) {
+            yield `(format('${schema.format}', ${value}))`;
+        }
+    }
+    function* Tuple(schema, value) {
+        yield `(Array.isArray(${value}))`;
+        if (schema.items === undefined)
+            return yield `(${value}.length === 0)`;
+        yield `(${value}.length === ${schema.maxItems})`;
+        for (let i = 0; i < schema.items.length; i++) {
+            const expression = CreateExpression(schema.items[i], `${value}[${i}]`);
+            yield `(${expression})`;
+        }
+    }
+    function* Undefined(schema, value) {
+        yield `(${value} === undefined)`;
+    }
+    function* Union(schema, value) {
+        const expressions = schema.anyOf.map((schema) => CreateExpression(schema, value));
+        yield `(${expressions.join(' || ')})`;
+    }
+    function* Uint8Array(schema, value) {
+        yield `(${value} instanceof Uint8Array)`;
+        if (schema.maxByteLength)
+            yield `(${value}.length <= ${schema.maxByteLength})`;
+        if (schema.minByteLength)
+            yield `(${value}.length >= ${schema.minByteLength})`;
+    }
+    function* Unknown(schema, value) {
+        yield '(true)';
+    }
+    function* Void(schema, value) {
+        yield `(${value} === null)`;
+    }
+    function* Visit(schema, value) {
+        // Reference: Referenced schemas can originate from either additional schemas
+        // or inline in the schema itself. Ideally the recursive path should align to
+        // reference path. Consider for refactor.
+        if (schema.$id && !names.has(schema.$id)) {
+            names.add(schema.$id);
+            const name = CreateFunctionName(schema.$id);
+            const body = CreateFunction(name, schema, 'value');
+            PushFunction(body);
+            yield `(${name}(${value}))`;
+            return;
+        }
+        const anySchema = schema;
+        switch (anySchema[Types.Kind]) {
+            case 'Any':
+                return yield* Any(anySchema, value);
+            case 'Array':
+                return yield* Array(anySchema, value);
+            case 'Boolean':
+                return yield* Boolean(anySchema, value);
+            case 'Constructor':
+                return yield* Constructor(anySchema, value);
+            case 'Function':
+                return yield* Function(anySchema, value);
+            case 'Integer':
+                return yield* Integer(anySchema, value);
+            case 'Literal':
+                return yield* Literal(anySchema, value);
+            case 'Never':
+                return yield* Never(anySchema, value);
+            case 'Null':
+                return yield* Null(anySchema, value);
+            case 'Number':
+                return yield* Number(anySchema, value);
+            case 'Object':
+                return yield* Object(anySchema, value);
+            case 'Promise':
+                return yield* Promise(anySchema, value);
+            case 'Record':
+                return yield* Record(anySchema, value);
+            case 'Ref':
+                return yield* Ref(anySchema, value);
+            case 'Self':
+                return yield* Self(anySchema, value);
+            case 'String':
+                return yield* String(anySchema, value);
+            case 'Tuple':
+                return yield* Tuple(anySchema, value);
+            case 'Undefined':
+                return yield* Undefined(anySchema, value);
+            case 'Union':
+                return yield* Union(anySchema, value);
+            case 'Uint8Array':
+                return yield* Uint8Array(anySchema, value);
+            case 'Unknown':
+                return yield* Unknown(anySchema, value);
+            case 'Void':
+                return yield* Void(anySchema, value);
+            default:
+                throw new TypeCompilerUnknownTypeError(schema);
+        }
+    }
+    // -------------------------------------------------------------------
+    // Compile State
+    // -------------------------------------------------------------------
+    const referenceMap = new Map();
+    const locals = new Set(); // local variables and functions
+    const names = new Set(); // cache of local functions
+    function ResetCompiler() {
+        referenceMap.clear();
+        locals.clear();
+        names.clear();
+    }
+    function AddReferences(schemas = []) {
+        for (const schema of schemas) {
+            if (!schema.$id)
+                throw new Error(`TypeCompiler: Referenced schemas must specify an $id.`);
+            if (referenceMap.has(schema.$id))
+                throw new Error(`TypeCompiler: Duplicate schema $id found for '${schema.$id}'`);
+            referenceMap.set(schema.$id, schema);
+        }
+    }
+    function CreateExpression(schema, value) {
+        return [...Visit(schema, value)].join(' && ');
+    }
+    function CreateFunctionName($id) {
+        return `check_${$id.replace(/-/g, '_')}`;
+    }
+    function CreateFunction(name, schema, value) {
+        const expression = [...Visit(schema, value)].map((condition) => `    ${condition}`).join(' &&\n');
+        return `function ${name}(value) {\n  return (\n${expression}\n )\n}`;
+    }
+    function PushFunction(functionBody) {
+        locals.add(functionBody);
+    }
+    function PushLocal(expression) {
+        const local = `local_${locals.size}`;
+        locals.add(`const ${local} = ${expression}`);
+        return local;
+    }
+    function GetLocals() {
+        return [...locals.values()];
+    }
+    // -------------------------------------------------------------------
+    // Compile
+    // -------------------------------------------------------------------
+    function Build(schema, references = []) {
+        ResetCompiler();
+        AddReferences(references);
+        const check = CreateFunction('check', schema, 'value');
+        const locals = GetLocals();
+        return `${locals.join('\n')}\nreturn ${check}`;
+    }
+    /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
+    function Compile(schema, references = []) {
+        index_2.TypeGuard.Assert(schema, references);
+        const code = Build(schema, references);
+        const func1 = globalThis.Function('format', code);
+        const func2 = func1((format, value) => {
+            if (!index_3.Format.Has(format))
+                return false;
+            const func = index_3.Format.Get(format);
+            return func(value);
+        });
+        return new TypeCheck(schema, references, func2, code);
+    }
+    TypeCompiler.Compile = Compile;
+})(TypeCompiler = exports.TypeCompiler || (exports.TypeCompiler = {}));
Index: frontend/node_modules/@sinclair/typebox/compiler/index.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/compiler/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/compiler/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2 @@
+export { ValueError, ValueErrorType } from '../errors/index';
+export * from './compiler';
Index: frontend/node_modules/@sinclair/typebox/compiler/index.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/compiler/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/compiler/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,47 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/compiler
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueErrorType = void 0;
+var index_1 = require("../errors/index");
+Object.defineProperty(exports, "ValueErrorType", { enumerable: true, get: function () { return index_1.ValueErrorType; } });
+__exportStar(require("./compiler"), exports);
Index: frontend/node_modules/@sinclair/typebox/conditional/conditional.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/conditional/conditional.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/conditional/conditional.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+import * as Types from '../typebox';
+export declare type TExtends<L extends Types.TSchema, R extends Types.TSchema, T extends Types.TSchema, U extends Types.TSchema> = Types.Static<L> extends Types.Static<R> ? T : U;
+export interface TExclude<T extends Types.TUnion, U extends Types.TUnion> extends Types.TUnion<any[]> {
+    static: Exclude<Types.Static<T, this['params']>, Types.Static<U, this['params']>>;
+}
+export interface TExtract<T extends Types.TSchema, U extends Types.TUnion> extends Types.TUnion<any[]> {
+    static: Extract<Types.Static<T, this['params']>, Types.Static<U, this['params']>>;
+}
+/** Conditional Types */
+export declare namespace Conditional {
+    /** (Experimental) Creates a conditional expression type */
+    function Extends<L extends Types.TSchema, R extends Types.TSchema, T extends Types.TSchema, U extends Types.TSchema>(left: L, right: R, ok: T, fail: U): TExtends<L, R, T, U>;
+    /** (Experimental) Constructs a type by excluding from UnionType all union members that are assignable to ExcludedMembers. */
+    function Exclude<T extends Types.TUnion, U extends Types.TUnion>(unionType: T, excludedMembers: U, options?: Types.SchemaOptions): TExclude<T, U>;
+    /** (Experimental) Constructs a type by extracting from Type all union members that are assignable to Union. */
+    function Extract<T extends Types.TSchema, U extends Types.TUnion>(type: T, union: U, options?: Types.SchemaOptions): TExtract<T, U>;
+}
Index: frontend/node_modules/@sinclair/typebox/conditional/conditional.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/conditional/conditional.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/conditional/conditional.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,91 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/conditional
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Conditional = void 0;
+const Types = require("../typebox");
+const structural_1 = require("./structural");
+const index_1 = require("../guard/index");
+/** Conditional Types */
+var Conditional;
+(function (Conditional) {
+    /** (Experimental) Creates a conditional expression type */
+    function Extends(left, right, ok, fail) {
+        switch (structural_1.Structural.Check(left, right)) {
+            case structural_1.StructuralResult.Union:
+                return Types.Type.Union([Clone(ok), Clone(fail)]);
+            case structural_1.StructuralResult.True:
+                return Clone(ok);
+            case structural_1.StructuralResult.False:
+                return Clone(fail);
+        }
+    }
+    Conditional.Extends = Extends;
+    /** (Experimental) Constructs a type by excluding from UnionType all union members that are assignable to ExcludedMembers. */
+    function Exclude(unionType, excludedMembers, options = {}) {
+        const anyOf = unionType.anyOf
+            .filter((schema) => {
+            const check = structural_1.Structural.Check(schema, excludedMembers);
+            return !(check === structural_1.StructuralResult.True || check === structural_1.StructuralResult.Union);
+        })
+            .map((schema) => Clone(schema));
+        return { ...options, [Types.Kind]: 'Union', anyOf };
+    }
+    Conditional.Exclude = Exclude;
+    /** (Experimental) Constructs a type by extracting from Type all union members that are assignable to Union. */
+    function Extract(type, union, options = {}) {
+        if (index_1.TypeGuard.TUnion(type)) {
+            const anyOf = type.anyOf.filter((schema) => structural_1.Structural.Check(schema, union) === structural_1.StructuralResult.True).map((schema) => Clone(schema));
+            return { ...options, [Types.Kind]: 'Union', anyOf };
+        }
+        else {
+            const anyOf = union.anyOf.filter((schema) => structural_1.Structural.Check(type, schema) === structural_1.StructuralResult.True).map((schema) => Clone(schema));
+            return { ...options, [Types.Kind]: 'Union', anyOf };
+        }
+    }
+    Conditional.Extract = Extract;
+    function Clone(value) {
+        const isObject = (object) => typeof object === 'object' && object !== null && !Array.isArray(object);
+        const isArray = (object) => typeof object === 'object' && object !== null && Array.isArray(object);
+        if (isObject(value)) {
+            return Object.keys(value).reduce((acc, key) => ({
+                ...acc,
+                [key]: Clone(value[key]),
+            }), Object.getOwnPropertySymbols(value).reduce((acc, key) => ({
+                ...acc,
+                [key]: Clone(value[key]),
+            }), {}));
+        }
+        else if (isArray(value)) {
+            return value.map((item) => Clone(item));
+        }
+        else {
+            return value;
+        }
+    }
+})(Conditional = exports.Conditional || (exports.Conditional = {}));
Index: frontend/node_modules/@sinclair/typebox/conditional/index.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/conditional/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/conditional/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2 @@
+export * from './conditional';
+export * from './structural';
Index: frontend/node_modules/@sinclair/typebox/conditional/index.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/conditional/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/conditional/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,45 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/conditional
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./conditional"), exports);
+__exportStar(require("./structural"), exports);
Index: frontend/node_modules/@sinclair/typebox/conditional/structural.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/conditional/structural.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/conditional/structural.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,11 @@
+import * as Types from '../typebox';
+export declare enum StructuralResult {
+    Union = 0,
+    True = 1,
+    False = 2
+}
+/** Performs structural equivalence checks against TypeBox types. */
+export declare namespace Structural {
+    /** Structurally tests if the left schema extends the right. */
+    function Check(left: Types.TSchema, right: Types.TSchema): StructuralResult;
+}
Index: frontend/node_modules/@sinclair/typebox/conditional/structural.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/conditional/structural.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/conditional/structural.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,657 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/conditional
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Structural = exports.StructuralResult = void 0;
+const Types = require("../typebox");
+const guard_1 = require("../guard");
+// --------------------------------------------------------------------------
+// StructuralResult
+// --------------------------------------------------------------------------
+var StructuralResult;
+(function (StructuralResult) {
+    StructuralResult[StructuralResult["Union"] = 0] = "Union";
+    StructuralResult[StructuralResult["True"] = 1] = "True";
+    StructuralResult[StructuralResult["False"] = 2] = "False";
+})(StructuralResult = exports.StructuralResult || (exports.StructuralResult = {}));
+// --------------------------------------------------------------------------
+// Structural
+// --------------------------------------------------------------------------
+/** Performs structural equivalence checks against TypeBox types. */
+var Structural;
+(function (Structural) {
+    const referenceMap = new Map();
+    // ------------------------------------------------------------------------
+    // Rules
+    // ------------------------------------------------------------------------
+    function AnyOrUnknownRule(right) {
+        // https://github.com/microsoft/TypeScript/issues/40049
+        if (right[Types.Kind] === 'Union' && right.anyOf.some((schema) => schema[Types.Kind] === 'Any' || schema[Types.Kind] === 'Unknown'))
+            return true;
+        if (right[Types.Kind] === 'Unknown')
+            return true;
+        if (right[Types.Kind] === 'Any')
+            return true;
+        return false;
+    }
+    function ObjectRightRule(left, right) {
+        // type A = boolean extends {}     ? 1 : 2 // additionalProperties: false
+        // type B = boolean extends object ? 1 : 2 // additionalProperties: true
+        const additionalProperties = right.additionalProperties;
+        const propertyLength = globalThis.Object.keys(right.properties).length;
+        return additionalProperties === false && propertyLength === 0;
+    }
+    function UnionRightRule(left, right) {
+        const result = right.anyOf.some((right) => Visit(left, right) !== StructuralResult.False);
+        return result ? StructuralResult.True : StructuralResult.False;
+    }
+    // ------------------------------------------------------------------------
+    // Records
+    // ------------------------------------------------------------------------
+    function RecordPattern(schema) {
+        return globalThis.Object.keys(schema.patternProperties)[0];
+    }
+    function RecordNumberOrStringKey(schema) {
+        const pattern = RecordPattern(schema);
+        return pattern === '^.*$' || pattern === '^(0|[1-9][0-9]*)$';
+    }
+    function RecordValue(schema) {
+        const pattern = RecordPattern(schema);
+        return schema.patternProperties[pattern];
+    }
+    function RecordKey(schema) {
+        const pattern = RecordPattern(schema);
+        if (pattern === '^.*$') {
+            return Types.Type.String();
+        }
+        else if (pattern === '^(0|[1-9][0-9]*)$') {
+            return Types.Type.Number();
+        }
+        else {
+            const keys = pattern.slice(1, pattern.length - 1).split('|');
+            const schemas = keys.map((key) => (isNaN(+key) ? Types.Type.Literal(key) : Types.Type.Literal(parseFloat(key))));
+            return Types.Type.Union(schemas);
+        }
+    }
+    function PropertyMap(schema) {
+        const comparable = new Map();
+        if (guard_1.TypeGuard.TRecord(schema)) {
+            const propertyPattern = RecordPattern(schema);
+            if (propertyPattern === '^.*$' || propertyPattern === '^(0|[1-9][0-9]*)$')
+                throw Error('Cannot extract record properties without property constraints');
+            const propertySchema = schema.patternProperties[propertyPattern];
+            const propertyKeys = propertyPattern.slice(1, propertyPattern.length - 1).split('|');
+            propertyKeys.forEach((propertyKey) => {
+                comparable.set(propertyKey, propertySchema);
+            });
+        }
+        else {
+            globalThis.Object.entries(schema.properties).forEach(([propertyKey, propertySchema]) => {
+                comparable.set(propertyKey, propertySchema);
+            });
+        }
+        return comparable;
+    }
+    // ------------------------------------------------------------------------
+    // Indexable
+    // ------------------------------------------------------------------------
+    function Indexable(left, right) {
+        if (guard_1.TypeGuard.TUnion(right)) {
+            return StructuralResult.False;
+        }
+        else {
+            return Visit(left, right);
+        }
+    }
+    // ------------------------------------------------------------------------
+    // Checks
+    // ------------------------------------------------------------------------
+    function Any(left, right) {
+        return AnyOrUnknownRule(right) ? StructuralResult.True : StructuralResult.Union;
+    }
+    function Array(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right)) {
+            if (right.properties['length'] !== undefined && right.properties['length'][Types.Kind] === 'Number')
+                return StructuralResult.True;
+            if (globalThis.Object.keys(right.properties).length === 0)
+                return StructuralResult.True;
+            return StructuralResult.False;
+        }
+        else if (!guard_1.TypeGuard.TArray(right)) {
+            return StructuralResult.False;
+        }
+        else if (left.items === undefined && right.items !== undefined) {
+            return StructuralResult.False;
+        }
+        else if (left.items !== undefined && right.items === undefined) {
+            return StructuralResult.False;
+        }
+        else if (left.items === undefined && right.items === undefined) {
+            return StructuralResult.False;
+        }
+        else {
+            const result = Visit(left.items, right.items) !== StructuralResult.False;
+            return result ? StructuralResult.True : StructuralResult.False;
+        }
+    }
+    function Boolean(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TBoolean(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnion(right)) {
+            return UnionRightRule(left, right);
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Constructor(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right) && globalThis.Object.keys(right.properties).length === 0) {
+            return StructuralResult.True;
+        }
+        else if (!guard_1.TypeGuard.TConstructor(right)) {
+            return StructuralResult.False;
+        }
+        else if (right.parameters.length < left.parameters.length) {
+            return StructuralResult.False;
+        }
+        else {
+            if (Visit(left.returns, right.returns) === StructuralResult.False) {
+                return StructuralResult.False;
+            }
+            for (let i = 0; i < left.parameters.length; i++) {
+                const result = Visit(right.parameters[i], left.parameters[i]);
+                if (result === StructuralResult.False)
+                    return StructuralResult.False;
+            }
+            return StructuralResult.True;
+        }
+    }
+    function Function(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right)) {
+            if (right.properties['length'] !== undefined && right.properties['length'][Types.Kind] === 'Number')
+                return StructuralResult.True;
+            if (globalThis.Object.keys(right.properties).length === 0)
+                return StructuralResult.True;
+            return StructuralResult.False;
+        }
+        else if (!guard_1.TypeGuard.TFunction(right)) {
+            return StructuralResult.False;
+        }
+        else if (right.parameters.length < left.parameters.length) {
+            return StructuralResult.False;
+        }
+        else if (Visit(left.returns, right.returns) === StructuralResult.False) {
+            return StructuralResult.False;
+        }
+        else {
+            for (let i = 0; i < left.parameters.length; i++) {
+                const result = Visit(right.parameters[i], left.parameters[i]);
+                if (result === StructuralResult.False)
+                    return StructuralResult.False;
+            }
+            return StructuralResult.True;
+        }
+    }
+    function Integer(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TInteger(right) || guard_1.TypeGuard.TNumber(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnion(right)) {
+            return UnionRightRule(left, right);
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Literal(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TRecord(right)) {
+            if (typeof left.const === 'string') {
+                return Indexable(left, RecordValue(right));
+            }
+            else {
+                return StructuralResult.False;
+            }
+        }
+        else if (guard_1.TypeGuard.TLiteral(right) && left.const === right.const) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TString(right) && typeof left.const === 'string') {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TNumber(right) && typeof left.const === 'number') {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TInteger(right) && typeof left.const === 'number') {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TBoolean(right) && typeof left.const === 'boolean') {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnion(right)) {
+            return UnionRightRule(left, right);
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Number(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TNumber(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TInteger(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnion(right)) {
+            return UnionRightRule(left, right);
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Null(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TNull(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnion(right)) {
+            return UnionRightRule(left, right);
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Properties(left, right) {
+        if (right.size > left.size)
+            return StructuralResult.False;
+        if (![...right.keys()].every((rightKey) => left.has(rightKey)))
+            return StructuralResult.False;
+        for (const rightKey of right.keys()) {
+            const leftProp = left.get(rightKey);
+            const rightProp = right.get(rightKey);
+            if (Visit(leftProp, rightProp) === StructuralResult.False) {
+                return StructuralResult.False;
+            }
+        }
+        return StructuralResult.True;
+    }
+    function Object(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right)) {
+            return Properties(PropertyMap(left), PropertyMap(right));
+        }
+        else if (guard_1.TypeGuard.TRecord(right)) {
+            if (!RecordNumberOrStringKey(right)) {
+                return Properties(PropertyMap(left), PropertyMap(right));
+            }
+            else {
+                return StructuralResult.True;
+            }
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Promise(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right)) {
+            if (ObjectRightRule(left, right) || globalThis.Object.keys(right.properties).length === 0) {
+                return StructuralResult.True;
+            }
+            else {
+                return StructuralResult.False;
+            }
+        }
+        else if (!guard_1.TypeGuard.TPromise(right)) {
+            return StructuralResult.False;
+        }
+        else {
+            const result = Visit(left.item, right.item) !== StructuralResult.False;
+            return result ? StructuralResult.True : StructuralResult.False;
+        }
+    }
+    function Record(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right)) {
+            if (RecordPattern(left) === '^.*$' && right[Types.Hint] === 'Record') {
+                return StructuralResult.True;
+            }
+            else if (RecordPattern(left) === '^.*$') {
+                return StructuralResult.False;
+            }
+            else {
+                return globalThis.Object.keys(right.properties).length === 0 ? StructuralResult.True : StructuralResult.False;
+            }
+        }
+        else if (guard_1.TypeGuard.TRecord(right)) {
+            if (!RecordNumberOrStringKey(left) && !RecordNumberOrStringKey(right)) {
+                return Properties(PropertyMap(left), PropertyMap(right));
+            }
+            else if (RecordNumberOrStringKey(left) && !RecordNumberOrStringKey(right)) {
+                const leftKey = RecordKey(left);
+                const rightKey = RecordKey(right);
+                if (Visit(rightKey, leftKey) === StructuralResult.False) {
+                    return StructuralResult.False;
+                }
+                else {
+                    return StructuralResult.True;
+                }
+            }
+            else {
+                return StructuralResult.True;
+            }
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Ref(left, right) {
+        if (!referenceMap.has(left.$ref))
+            throw Error(`Cannot locate referenced $id '${left.$ref}'`);
+        const resolved = referenceMap.get(left.$ref);
+        return Visit(resolved, right);
+    }
+    function Self(left, right) {
+        if (!referenceMap.has(left.$ref))
+            throw Error(`Cannot locate referenced self $id '${left.$ref}'`);
+        const resolved = referenceMap.get(left.$ref);
+        return Visit(resolved, right);
+    }
+    function String(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TRecord(right)) {
+            return Indexable(left, RecordValue(right));
+        }
+        else if (guard_1.TypeGuard.TString(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnion(right)) {
+            return UnionRightRule(left, right);
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Tuple(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right)) {
+            const result = ObjectRightRule(left, right) || globalThis.Object.keys(right.properties).length === 0;
+            return result ? StructuralResult.True : StructuralResult.False;
+        }
+        else if (guard_1.TypeGuard.TRecord(right)) {
+            return Indexable(left, RecordValue(right));
+        }
+        else if (guard_1.TypeGuard.TArray(right)) {
+            if (right.items === undefined) {
+                return StructuralResult.False;
+            }
+            else if (guard_1.TypeGuard.TUnion(right.items) && left.items) {
+                const result = left.items.every((left) => UnionRightRule(left, right.items) !== StructuralResult.False);
+                return result ? StructuralResult.True : StructuralResult.False;
+            }
+            else if (guard_1.TypeGuard.TAny(right.items)) {
+                return StructuralResult.True;
+            }
+            else {
+                return StructuralResult.False;
+            }
+        }
+        if (!guard_1.TypeGuard.TTuple(right))
+            return StructuralResult.False;
+        if (left.items === undefined && right.items === undefined)
+            return StructuralResult.True;
+        if (left.items === undefined && right.items !== undefined)
+            return StructuralResult.False;
+        if (left.items !== undefined && right.items === undefined)
+            return StructuralResult.False;
+        if (left.items === undefined && right.items === undefined)
+            return StructuralResult.True;
+        if (left.minItems !== right.minItems || left.maxItems !== right.maxItems)
+            return StructuralResult.False;
+        for (let i = 0; i < left.items.length; i++) {
+            if (Visit(left.items[i], right.items[i]) === StructuralResult.False)
+                return StructuralResult.False;
+        }
+        return StructuralResult.True;
+    }
+    function Uint8Array(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TRecord(right)) {
+            return Indexable(left, RecordValue(right));
+        }
+        else if (guard_1.TypeGuard.TUint8Array(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnion(right)) {
+            return UnionRightRule(left, right);
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Undefined(left, right) {
+        if (AnyOrUnknownRule(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUndefined(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TVoid(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnion(right)) {
+            return UnionRightRule(left, right);
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Union(left, right) {
+        if (left.anyOf.some((left) => guard_1.TypeGuard.TAny(left))) {
+            return StructuralResult.Union;
+        }
+        else if (guard_1.TypeGuard.TUnion(right)) {
+            const result = left.anyOf.every((left) => right.anyOf.some((right) => Visit(left, right) !== StructuralResult.False));
+            return result ? StructuralResult.True : StructuralResult.False;
+        }
+        else {
+            const result = left.anyOf.every((left) => Visit(left, right) !== StructuralResult.False);
+            return result ? StructuralResult.True : StructuralResult.False;
+        }
+    }
+    function Unknown(left, right) {
+        if (guard_1.TypeGuard.TUnion(right)) {
+            const result = right.anyOf.some((right) => guard_1.TypeGuard.TAny(right) || guard_1.TypeGuard.TUnknown(right));
+            return result ? StructuralResult.True : StructuralResult.False;
+        }
+        else if (guard_1.TypeGuard.TAny(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnknown(right)) {
+            return StructuralResult.True;
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    function Void(left, right) {
+        if (guard_1.TypeGuard.TUnion(right)) {
+            const result = right.anyOf.some((right) => guard_1.TypeGuard.TAny(right) || guard_1.TypeGuard.TUnknown(right));
+            return result ? StructuralResult.True : StructuralResult.False;
+        }
+        else if (guard_1.TypeGuard.TAny(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TUnknown(right)) {
+            return StructuralResult.True;
+        }
+        else if (guard_1.TypeGuard.TVoid(right)) {
+            return StructuralResult.True;
+        }
+        else {
+            return StructuralResult.False;
+        }
+    }
+    let recursionDepth = 0;
+    function Visit(left, right) {
+        recursionDepth += 1;
+        if (recursionDepth >= 1000)
+            return StructuralResult.True;
+        if (left.$id !== undefined)
+            referenceMap.set(left.$id, left);
+        if (right.$id !== undefined)
+            referenceMap.set(right.$id, right);
+        const resolvedRight = right[Types.Kind] === 'Self' ? referenceMap.get(right.$ref) : right;
+        if (guard_1.TypeGuard.TAny(left)) {
+            return Any(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TArray(left)) {
+            return Array(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TBoolean(left)) {
+            return Boolean(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TConstructor(left)) {
+            return Constructor(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TFunction(left)) {
+            return Function(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TInteger(left)) {
+            return Integer(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TLiteral(left)) {
+            return Literal(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TNull(left)) {
+            return Null(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TNumber(left)) {
+            return Number(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TObject(left)) {
+            return Object(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TPromise(left)) {
+            return Promise(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TRecord(left)) {
+            return Record(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TRef(left)) {
+            return Ref(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TSelf(left)) {
+            return Self(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TString(left)) {
+            return String(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TTuple(left)) {
+            return Tuple(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TUndefined(left)) {
+            return Undefined(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TUint8Array(left)) {
+            return Uint8Array(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TUnion(left)) {
+            return Union(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TUnknown(left)) {
+            return Unknown(left, resolvedRight);
+        }
+        else if (guard_1.TypeGuard.TVoid(left)) {
+            return Void(left, resolvedRight);
+        }
+        else {
+            throw Error(`Structural: Unknown left operand '${left[Types.Kind]}'`);
+        }
+    }
+    /** Structurally tests if the left schema extends the right. */
+    function Check(left, right) {
+        referenceMap.clear();
+        recursionDepth = 0;
+        return Visit(left, right);
+    }
+    Structural.Check = Check;
+})(Structural = exports.Structural || (exports.Structural = {}));
Index: frontend/node_modules/@sinclair/typebox/errors/errors.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/errors/errors.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/errors/errors.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,60 @@
+import * as Types from '../typebox';
+export declare enum ValueErrorType {
+    Array = 0,
+    ArrayMinItems = 1,
+    ArrayMaxItems = 2,
+    ArrayUniqueItems = 3,
+    Boolean = 4,
+    Function = 5,
+    Integer = 6,
+    IntegerMultipleOf = 7,
+    IntegerExclusiveMinimum = 8,
+    IntegerExclusiveMaximum = 9,
+    IntegerMinimum = 10,
+    IntegerMaximum = 11,
+    Literal = 12,
+    Never = 13,
+    Null = 14,
+    Number = 15,
+    NumberMultipleOf = 16,
+    NumberExclusiveMinimum = 17,
+    NumberExclusiveMaximum = 18,
+    NumberMinumum = 19,
+    NumberMaximum = 20,
+    Object = 21,
+    ObjectMinProperties = 22,
+    ObjectMaxProperties = 23,
+    ObjectAdditionalProperties = 24,
+    ObjectRequiredProperties = 25,
+    Promise = 26,
+    RecordKeyNumeric = 27,
+    RecordKeyString = 28,
+    String = 29,
+    StringMinLength = 30,
+    StringMaxLength = 31,
+    StringPattern = 32,
+    StringFormatUnknown = 33,
+    StringFormat = 34,
+    TupleZeroLength = 35,
+    TupleLength = 36,
+    Undefined = 37,
+    Union = 38,
+    Uint8Array = 39,
+    Uint8ArrayMinByteLength = 40,
+    Uint8ArrayMaxByteLength = 41,
+    Void = 42
+}
+export interface ValueError {
+    type: ValueErrorType;
+    schema: Types.TSchema;
+    path: string;
+    value: unknown;
+    message: string;
+}
+export declare class ValueErrorsUnknownTypeError extends Error {
+    readonly schema: Types.TSchema;
+    constructor(schema: Types.TSchema);
+}
+export declare namespace ValueErrors {
+    function Errors<T extends Types.TSchema>(schema: T, references: Types.TSchema[], value: any): IterableIterator<ValueError>;
+}
Index: frontend/node_modules/@sinclair/typebox/errors/errors.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/errors/errors.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/errors/errors.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,398 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/errors
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueErrors = exports.ValueErrorsUnknownTypeError = exports.ValueErrorType = void 0;
+const Types = require("../typebox");
+const index_1 = require("../format/index");
+// -------------------------------------------------------------------
+// ValueErrorType
+// -------------------------------------------------------------------
+var ValueErrorType;
+(function (ValueErrorType) {
+    ValueErrorType[ValueErrorType["Array"] = 0] = "Array";
+    ValueErrorType[ValueErrorType["ArrayMinItems"] = 1] = "ArrayMinItems";
+    ValueErrorType[ValueErrorType["ArrayMaxItems"] = 2] = "ArrayMaxItems";
+    ValueErrorType[ValueErrorType["ArrayUniqueItems"] = 3] = "ArrayUniqueItems";
+    ValueErrorType[ValueErrorType["Boolean"] = 4] = "Boolean";
+    ValueErrorType[ValueErrorType["Function"] = 5] = "Function";
+    ValueErrorType[ValueErrorType["Integer"] = 6] = "Integer";
+    ValueErrorType[ValueErrorType["IntegerMultipleOf"] = 7] = "IntegerMultipleOf";
+    ValueErrorType[ValueErrorType["IntegerExclusiveMinimum"] = 8] = "IntegerExclusiveMinimum";
+    ValueErrorType[ValueErrorType["IntegerExclusiveMaximum"] = 9] = "IntegerExclusiveMaximum";
+    ValueErrorType[ValueErrorType["IntegerMinimum"] = 10] = "IntegerMinimum";
+    ValueErrorType[ValueErrorType["IntegerMaximum"] = 11] = "IntegerMaximum";
+    ValueErrorType[ValueErrorType["Literal"] = 12] = "Literal";
+    ValueErrorType[ValueErrorType["Never"] = 13] = "Never";
+    ValueErrorType[ValueErrorType["Null"] = 14] = "Null";
+    ValueErrorType[ValueErrorType["Number"] = 15] = "Number";
+    ValueErrorType[ValueErrorType["NumberMultipleOf"] = 16] = "NumberMultipleOf";
+    ValueErrorType[ValueErrorType["NumberExclusiveMinimum"] = 17] = "NumberExclusiveMinimum";
+    ValueErrorType[ValueErrorType["NumberExclusiveMaximum"] = 18] = "NumberExclusiveMaximum";
+    ValueErrorType[ValueErrorType["NumberMinumum"] = 19] = "NumberMinumum";
+    ValueErrorType[ValueErrorType["NumberMaximum"] = 20] = "NumberMaximum";
+    ValueErrorType[ValueErrorType["Object"] = 21] = "Object";
+    ValueErrorType[ValueErrorType["ObjectMinProperties"] = 22] = "ObjectMinProperties";
+    ValueErrorType[ValueErrorType["ObjectMaxProperties"] = 23] = "ObjectMaxProperties";
+    ValueErrorType[ValueErrorType["ObjectAdditionalProperties"] = 24] = "ObjectAdditionalProperties";
+    ValueErrorType[ValueErrorType["ObjectRequiredProperties"] = 25] = "ObjectRequiredProperties";
+    ValueErrorType[ValueErrorType["Promise"] = 26] = "Promise";
+    ValueErrorType[ValueErrorType["RecordKeyNumeric"] = 27] = "RecordKeyNumeric";
+    ValueErrorType[ValueErrorType["RecordKeyString"] = 28] = "RecordKeyString";
+    ValueErrorType[ValueErrorType["String"] = 29] = "String";
+    ValueErrorType[ValueErrorType["StringMinLength"] = 30] = "StringMinLength";
+    ValueErrorType[ValueErrorType["StringMaxLength"] = 31] = "StringMaxLength";
+    ValueErrorType[ValueErrorType["StringPattern"] = 32] = "StringPattern";
+    ValueErrorType[ValueErrorType["StringFormatUnknown"] = 33] = "StringFormatUnknown";
+    ValueErrorType[ValueErrorType["StringFormat"] = 34] = "StringFormat";
+    ValueErrorType[ValueErrorType["TupleZeroLength"] = 35] = "TupleZeroLength";
+    ValueErrorType[ValueErrorType["TupleLength"] = 36] = "TupleLength";
+    ValueErrorType[ValueErrorType["Undefined"] = 37] = "Undefined";
+    ValueErrorType[ValueErrorType["Union"] = 38] = "Union";
+    ValueErrorType[ValueErrorType["Uint8Array"] = 39] = "Uint8Array";
+    ValueErrorType[ValueErrorType["Uint8ArrayMinByteLength"] = 40] = "Uint8ArrayMinByteLength";
+    ValueErrorType[ValueErrorType["Uint8ArrayMaxByteLength"] = 41] = "Uint8ArrayMaxByteLength";
+    ValueErrorType[ValueErrorType["Void"] = 42] = "Void";
+})(ValueErrorType = exports.ValueErrorType || (exports.ValueErrorType = {}));
+// -------------------------------------------------------------------
+// ValueErrors
+// -------------------------------------------------------------------
+class ValueErrorsUnknownTypeError extends Error {
+    constructor(schema) {
+        super('ValueErrors: Unknown type');
+        this.schema = schema;
+    }
+}
+exports.ValueErrorsUnknownTypeError = ValueErrorsUnknownTypeError;
+var ValueErrors;
+(function (ValueErrors) {
+    function* Any(schema, references, path, value) { }
+    function* Array(schema, references, path, value) {
+        if (!globalThis.Array.isArray(value)) {
+            return yield { type: ValueErrorType.Array, schema, path, value, message: `Expected array` };
+        }
+        if (schema.minItems !== undefined && !(value.length >= schema.minItems)) {
+            yield { type: ValueErrorType.ArrayMinItems, schema, path, value, message: `Expected array length to be greater or equal to ${schema.minItems}` };
+        }
+        if (schema.maxItems !== undefined && !(value.length <= schema.maxItems)) {
+            yield { type: ValueErrorType.ArrayMinItems, schema, path, value, message: `Expected array length to be less or equal to ${schema.maxItems}` };
+        }
+        if (schema.uniqueItems === true && !(new Set(value).size === value.length)) {
+            yield { type: ValueErrorType.ArrayUniqueItems, schema, path, value, message: `Expected array elements to be unique` };
+        }
+        for (let i = 0; i < value.length; i++) {
+            yield* Visit(schema.items, references, `${path}/${i}`, value[i]);
+        }
+    }
+    function* Boolean(schema, references, path, value) {
+        if (!(typeof value === 'boolean')) {
+            return yield { type: ValueErrorType.Boolean, schema, path, value, message: `Expected boolean` };
+        }
+    }
+    function* Constructor(schema, references, path, value) {
+        yield* Visit(schema.returns, references, path, value.prototype);
+    }
+    function* Function(schema, references, path, value) {
+        if (!(typeof value === 'function')) {
+            return yield { type: ValueErrorType.Function, schema, path, value, message: `Expected function` };
+        }
+    }
+    function* Integer(schema, references, path, value) {
+        if (!(typeof value === 'number')) {
+            return yield { type: ValueErrorType.Number, schema, path, value, message: `Expected number` };
+        }
+        if (!globalThis.Number.isInteger(value)) {
+            yield { type: ValueErrorType.Integer, schema, path, value, message: `Expected integer` };
+        }
+        if (schema.multipleOf && !(value % schema.multipleOf === 0)) {
+            yield { type: ValueErrorType.IntegerMultipleOf, schema, path, value, message: `Expected integer to be a multiple of ${schema.multipleOf}` };
+        }
+        if (schema.exclusiveMinimum && !(value > schema.exclusiveMinimum)) {
+            yield { type: ValueErrorType.IntegerExclusiveMinimum, schema, path, value, message: `Expected integer to be greater than ${schema.exclusiveMinimum}` };
+        }
+        if (schema.exclusiveMaximum && !(value < schema.exclusiveMaximum)) {
+            yield { type: ValueErrorType.IntegerExclusiveMaximum, schema, path, value, message: `Expected integer to be less than ${schema.exclusiveMaximum}` };
+        }
+        if (schema.minimum && !(value >= schema.minimum)) {
+            yield { type: ValueErrorType.IntegerMinimum, schema, path, value, message: `Expected integer to be greater or equal to ${schema.minimum}` };
+        }
+        if (schema.maximum && !(value <= schema.maximum)) {
+            yield { type: ValueErrorType.IntegerMaximum, schema, path, value, message: `Expected integer to be less or equal to ${schema.maximum}` };
+        }
+    }
+    function* Literal(schema, references, path, value) {
+        if (!(value === schema.const)) {
+            const error = typeof schema.const === 'string' ? `'${schema.const}'` : schema.const;
+            return yield { type: ValueErrorType.Literal, schema, path, value, message: `Expected ${error}` };
+        }
+    }
+    function* Never(schema, references, path, value) {
+        yield { type: ValueErrorType.Never, schema, path, value, message: `Value cannot be validated` };
+    }
+    function* Null(schema, references, path, value) {
+        if (!(value === null)) {
+            return yield { type: ValueErrorType.Null, schema, path, value, message: `Expected null` };
+        }
+    }
+    function* Number(schema, references, path, value) {
+        if (!(typeof value === 'number')) {
+            return yield { type: ValueErrorType.Number, schema, path, value, message: `Expected number` };
+        }
+        if (schema.multipleOf && !(value % schema.multipleOf === 0)) {
+            yield { type: ValueErrorType.NumberMultipleOf, schema, path, value, message: `Expected number to be a multiple of ${schema.multipleOf}` };
+        }
+        if (schema.exclusiveMinimum && !(value > schema.exclusiveMinimum)) {
+            yield { type: ValueErrorType.NumberExclusiveMinimum, schema, path, value, message: `Expected number to be greater than ${schema.exclusiveMinimum}` };
+        }
+        if (schema.exclusiveMaximum && !(value < schema.exclusiveMaximum)) {
+            yield { type: ValueErrorType.NumberExclusiveMaximum, schema, path, value, message: `Expected number to be less than ${schema.exclusiveMaximum}` };
+        }
+        if (schema.minimum && !(value >= schema.minimum)) {
+            yield { type: ValueErrorType.NumberMaximum, schema, path, value, message: `Expected number to be greater or equal to ${schema.minimum}` };
+        }
+        if (schema.maximum && !(value <= schema.maximum)) {
+            yield { type: ValueErrorType.NumberMinumum, schema, path, value, message: `Expected number to be less or equal to ${schema.maximum}` };
+        }
+    }
+    function* Object(schema, references, path, value) {
+        if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
+            return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
+        }
+        if (schema.minProperties !== undefined && !(globalThis.Object.keys(value).length >= schema.minProperties)) {
+            yield { type: ValueErrorType.ObjectMinProperties, schema, path, value, message: `Expected object to have at least ${schema.minProperties} properties` };
+        }
+        if (schema.maxProperties !== undefined && !(globalThis.Object.keys(value).length <= schema.maxProperties)) {
+            yield { type: ValueErrorType.ObjectMaxProperties, schema, path, value, message: `Expected object to have less than ${schema.minProperties} properties` };
+        }
+        const propertyKeys = globalThis.Object.keys(schema.properties);
+        if (schema.additionalProperties === false) {
+            for (const objectKey of globalThis.Object.keys(value)) {
+                if (!propertyKeys.includes(objectKey)) {
+                    yield { type: ValueErrorType.ObjectAdditionalProperties, schema, path: `${path}/${objectKey}`, value: value[objectKey], message: `Unexpected property` };
+                }
+            }
+        }
+        if (schema.required && schema.required.length > 0) {
+            const objectKeys = globalThis.Object.keys(value);
+            for (const requiredKey of schema.required) {
+                if (objectKeys.includes(requiredKey))
+                    continue;
+                yield { type: ValueErrorType.ObjectRequiredProperties, schema: schema.properties[requiredKey], path: `${path}/${requiredKey}`, value: undefined, message: `Expected required property` };
+            }
+        }
+        if (typeof schema.additionalProperties === 'object') {
+            for (const objectKey of globalThis.Object.keys(value)) {
+                if (propertyKeys.includes(objectKey))
+                    continue;
+                yield* Visit(schema.additionalProperties, references, `${path}/${objectKey}`, value[objectKey]);
+            }
+        }
+        for (const propertyKey of propertyKeys) {
+            const propertySchema = schema.properties[propertyKey];
+            if (schema.required && schema.required.includes(propertyKey)) {
+                yield* Visit(propertySchema, references, `${path}/${propertyKey}`, value[propertyKey]);
+            }
+            else {
+                if (value[propertyKey] !== undefined) {
+                    yield* Visit(propertySchema, references, `${path}/${propertyKey}`, value[propertyKey]);
+                }
+            }
+        }
+    }
+    function* Promise(schema, references, path, value) {
+        if (!(typeof value === 'object' && typeof value.then === 'function')) {
+            yield { type: ValueErrorType.Promise, schema, path, value, message: `Expected Promise` };
+        }
+    }
+    function* Record(schema, references, path, value) {
+        if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
+            return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
+        }
+        const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
+        const regex = new RegExp(keyPattern);
+        if (!globalThis.Object.keys(value).every((key) => regex.test(key))) {
+            const numeric = keyPattern === '^(0|[1-9][0-9]*)$';
+            const type = numeric ? ValueErrorType.RecordKeyNumeric : ValueErrorType.RecordKeyString;
+            const message = numeric ? 'Expected all object property keys to be numeric' : 'Expected all object property keys to be strings';
+            return yield { type, schema, path, value, message };
+        }
+        for (const [propKey, propValue] of globalThis.Object.entries(value)) {
+            yield* Visit(valueSchema, references, `${path}/${propKey}`, propValue);
+        }
+    }
+    function* Ref(schema, references, path, value) {
+        const reference = references.find((reference) => reference.$id === schema.$ref);
+        if (reference === undefined)
+            throw new Error(`ValueErrors.Ref: Cannot find schema with $id '${schema.$ref}'.`);
+        yield* Visit(reference, references, path, value);
+    }
+    function* Self(schema, references, path, value) {
+        const reference = references.find((reference) => reference.$id === schema.$ref);
+        if (reference === undefined)
+            throw new Error(`ValueErrors.Self: Cannot find schema with $id '${schema.$ref}'.`);
+        yield* Visit(reference, references, path, value);
+    }
+    function* String(schema, references, path, value) {
+        if (!(typeof value === 'string')) {
+            return yield { type: ValueErrorType.String, schema, path, value, message: 'Expected string' };
+        }
+        if (schema.minLength !== undefined && !(value.length >= schema.minLength)) {
+            yield { type: ValueErrorType.StringMinLength, schema, path, value, message: `Expected string length greater or equal to ${schema.minLength}` };
+        }
+        if (schema.maxLength !== undefined && !(value.length <= schema.maxLength)) {
+            yield { type: ValueErrorType.StringMaxLength, schema, path, value, message: `Expected string length less or equal to ${schema.maxLength}` };
+        }
+        if (schema.pattern !== undefined) {
+            const regex = new RegExp(schema.pattern);
+            if (!regex.test(value)) {
+                yield { type: ValueErrorType.StringPattern, schema, path, value, message: `Expected string to match pattern ${schema.pattern}` };
+            }
+        }
+        if (schema.format !== undefined) {
+            if (!index_1.Format.Has(schema.format)) {
+                yield { type: ValueErrorType.StringFormatUnknown, schema, path, value, message: `Unknown string format '${schema.format}'` };
+            }
+            else {
+                const format = index_1.Format.Get(schema.format);
+                if (!format(value)) {
+                    yield { type: ValueErrorType.StringFormat, schema, path, value, message: `Expected string to match format '${schema.format}'` };
+                }
+            }
+        }
+    }
+    function* Tuple(schema, references, path, value) {
+        if (!globalThis.Array.isArray(value)) {
+            return yield { type: ValueErrorType.Array, schema, path, value, message: 'Expected Array' };
+        }
+        if (schema.items === undefined && !(value.length === 0)) {
+            return yield { type: ValueErrorType.TupleZeroLength, schema, path, value, message: 'Expected tuple to have 0 elements' };
+        }
+        if (!(value.length === schema.maxItems)) {
+            yield { type: ValueErrorType.TupleLength, schema, path, value, message: `Expected tuple to have ${schema.maxItems} elements` };
+        }
+        if (!schema.items) {
+            return;
+        }
+        for (let i = 0; i < schema.items.length; i++) {
+            yield* Visit(schema.items[i], references, `${path}/${i}`, value[i]);
+        }
+    }
+    function* Undefined(schema, references, path, value) {
+        if (!(value === undefined)) {
+            yield { type: ValueErrorType.Undefined, schema, path, value, message: `Expected undefined` };
+        }
+    }
+    function* Union(schema, references, path, value) {
+        const errors = [];
+        for (const inner of schema.anyOf) {
+            const variantErrors = [...Visit(inner, references, path, value)];
+            if (variantErrors.length === 0)
+                return;
+            errors.push(...variantErrors);
+        }
+        for (const error of errors) {
+            yield error;
+        }
+        if (errors.length > 0) {
+            yield { type: ValueErrorType.Union, schema, path, value, message: 'Expected value of union' };
+        }
+    }
+    function* Uint8Array(schema, references, path, value) {
+        if (!(value instanceof globalThis.Uint8Array)) {
+            return yield { type: ValueErrorType.Uint8Array, schema, path, value, message: `Expected Uint8Array` };
+        }
+        if (schema.maxByteLength && !(value.length <= schema.maxByteLength)) {
+            yield { type: ValueErrorType.Uint8ArrayMaxByteLength, schema, path, value, message: `Expected Uint8Array to have a byte length less or equal to ${schema.maxByteLength}` };
+        }
+        if (schema.minByteLength && !(value.length >= schema.minByteLength)) {
+            yield { type: ValueErrorType.Uint8ArrayMinByteLength, schema, path, value, message: `Expected Uint8Array to have a byte length greater or equal to ${schema.maxByteLength}` };
+        }
+    }
+    function* Unknown(schema, references, path, value) { }
+    function* Void(schema, references, path, value) {
+        if (!(value === null)) {
+            return yield { type: ValueErrorType.Void, schema, path, value, message: `Expected null` };
+        }
+    }
+    function* Visit(schema, references, path, value) {
+        const anyReferences = schema.$id === undefined ? references : [schema, ...references];
+        const anySchema = schema;
+        switch (anySchema[Types.Kind]) {
+            case 'Any':
+                return yield* Any(anySchema, anyReferences, path, value);
+            case 'Array':
+                return yield* Array(anySchema, anyReferences, path, value);
+            case 'Boolean':
+                return yield* Boolean(anySchema, anyReferences, path, value);
+            case 'Constructor':
+                return yield* Constructor(anySchema, anyReferences, path, value);
+            case 'Function':
+                return yield* Function(anySchema, anyReferences, path, value);
+            case 'Integer':
+                return yield* Integer(anySchema, anyReferences, path, value);
+            case 'Literal':
+                return yield* Literal(anySchema, anyReferences, path, value);
+            case 'Never':
+                return yield* Never(anySchema, anyReferences, path, value);
+            case 'Null':
+                return yield* Null(anySchema, anyReferences, path, value);
+            case 'Number':
+                return yield* Number(anySchema, anyReferences, path, value);
+            case 'Object':
+                return yield* Object(anySchema, anyReferences, path, value);
+            case 'Promise':
+                return yield* Promise(anySchema, anyReferences, path, value);
+            case 'Record':
+                return yield* Record(anySchema, anyReferences, path, value);
+            case 'Ref':
+                return yield* Ref(anySchema, anyReferences, path, value);
+            case 'Self':
+                return yield* Self(anySchema, anyReferences, path, value);
+            case 'String':
+                return yield* String(anySchema, anyReferences, path, value);
+            case 'Tuple':
+                return yield* Tuple(anySchema, anyReferences, path, value);
+            case 'Undefined':
+                return yield* Undefined(anySchema, anyReferences, path, value);
+            case 'Union':
+                return yield* Union(anySchema, anyReferences, path, value);
+            case 'Uint8Array':
+                return yield* Uint8Array(anySchema, anyReferences, path, value);
+            case 'Unknown':
+                return yield* Unknown(anySchema, anyReferences, path, value);
+            case 'Void':
+                return yield* Void(anySchema, anyReferences, path, value);
+            default:
+                throw new ValueErrorsUnknownTypeError(schema);
+        }
+    }
+    function* Errors(schema, references, value) {
+        yield* Visit(schema, references, '', value);
+    }
+    ValueErrors.Errors = Errors;
+})(ValueErrors = exports.ValueErrors || (exports.ValueErrors = {}));
Index: frontend/node_modules/@sinclair/typebox/errors/index.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/errors/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/errors/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './errors';
Index: frontend/node_modules/@sinclair/typebox/errors/index.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/errors/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/errors/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,44 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/errors
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./errors"), exports);
Index: frontend/node_modules/@sinclair/typebox/format/format.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/format/format.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/format/format.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,12 @@
+export declare type FormatValidationFunction = (value: string) => boolean;
+/** Shared string formats used by the TypeCompiler and Value modules */
+export declare namespace Format {
+    /** Clears all formats */
+    function Clear(): void;
+    /** Returns true if the string format exists */
+    function Has(format: string): boolean;
+    /** Sets a string format validation function */
+    function Set(format: string, func: FormatValidationFunction): void;
+    /** Gets a string format validation function */
+    function Get(format: string): FormatValidationFunction | undefined;
+}
Index: frontend/node_modules/@sinclair/typebox/format/format.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/format/format.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/format/format.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,55 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/format
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Format = void 0;
+/** Shared string formats used by the TypeCompiler and Value modules */
+var Format;
+(function (Format) {
+    const formats = new Map();
+    /** Clears all formats */
+    function Clear() {
+        return formats.clear();
+    }
+    Format.Clear = Clear;
+    /** Returns true if the string format exists */
+    function Has(format) {
+        return formats.has(format);
+    }
+    Format.Has = Has;
+    /** Sets a string format validation function */
+    function Set(format, func) {
+        formats.set(format, func);
+    }
+    Format.Set = Set;
+    /** Gets a string format validation function */
+    function Get(format) {
+        return formats.get(format);
+    }
+    Format.Get = Get;
+})(Format = exports.Format || (exports.Format = {}));
Index: frontend/node_modules/@sinclair/typebox/format/index.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/format/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/format/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './format';
Index: frontend/node_modules/@sinclair/typebox/format/index.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/format/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/format/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,44 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/format
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./format"), exports);
Index: frontend/node_modules/@sinclair/typebox/guard/guard.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/guard/guard.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/guard/guard.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,56 @@
+import * as Types from '../typebox';
+export declare class TypeGuardInvalidTypeError extends Error {
+    readonly schema: unknown;
+    constructor(schema: unknown);
+}
+/** TypeGuard tests that values conform to a known TypeBox type specification */
+export declare namespace TypeGuard {
+    /** Returns true if the given schema is TAny */
+    function TAny(schema: unknown): schema is Types.TAny;
+    /** Returns true if the given schema is TArray */
+    function TArray(schema: unknown): schema is Types.TArray;
+    /** Returns true if the given schema is TBoolean */
+    function TBoolean(schema: unknown): schema is Types.TBoolean;
+    /** Returns true if the given schema is TConstructor */
+    function TConstructor(schema: unknown): schema is Types.TConstructor;
+    /** Returns true if the given schema is TFunction */
+    function TFunction(schema: unknown): schema is Types.TFunction;
+    /** Returns true if the given schema is TInteger */
+    function TInteger(schema: unknown): schema is Types.TInteger;
+    /** Returns true if the given schema is TLiteral */
+    function TLiteral(schema: unknown): schema is Types.TLiteral;
+    /** Returns true if the given schema is TNever */
+    function TNever(schema: unknown): schema is Types.TNever;
+    /** Returns true if the given schema is TNull */
+    function TNull(schema: unknown): schema is Types.TNull;
+    /** Returns true if the given schema is TNumber */
+    function TNumber(schema: unknown): schema is Types.TNumber;
+    /** Returns true if the given schema is TObject */
+    function TObject(schema: unknown): schema is Types.TObject;
+    /** Returns true if the given schema is TPromise */
+    function TPromise(schema: unknown): schema is Types.TPromise;
+    /** Returns true if the given schema is TRecord */
+    function TRecord(schema: unknown): schema is Types.TRecord;
+    /** Returns true if the given schema is TSelf */
+    function TSelf(schema: unknown): schema is Types.TSelf;
+    /** Returns true if the given schema is TRef */
+    function TRef(schema: unknown): schema is Types.TRef;
+    /** Returns true if the given schema is TString */
+    function TString(schema: unknown): schema is Types.TString;
+    /** Returns true if the given schema is TTuple */
+    function TTuple(schema: unknown): schema is Types.TTuple;
+    /** Returns true if the given schema is TUndefined */
+    function TUndefined(schema: unknown): schema is Types.TUndefined;
+    /** Returns true if the given schema is TUnion */
+    function TUnion(schema: unknown): schema is Types.TUnion;
+    /** Returns true if the given schema is TUint8Array */
+    function TUint8Array(schema: unknown): schema is Types.TUint8Array;
+    /** Returns true if the given schema is TUnknown */
+    function TUnknown(schema: unknown): schema is Types.TUnknown;
+    /** Returns true if the given schema is TVoid */
+    function TVoid(schema: unknown): schema is Types.TVoid;
+    /** Returns true if the given schema is TSchema */
+    function TSchema(schema: unknown): schema is Types.TSchema;
+    /** Asserts if this schema and associated references are valid. */
+    function Assert<T extends Types.TSchema>(schema: T, references?: Types.TSchema[]): void;
+}
Index: frontend/node_modules/@sinclair/typebox/guard/guard.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/guard/guard.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/guard/guard.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,351 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/guard
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, dTribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TypeGuard = exports.TypeGuardInvalidTypeError = void 0;
+const Types = require("../typebox");
+class TypeGuardInvalidTypeError extends Error {
+    constructor(schema) {
+        super('TypeGuard: Invalid type');
+        this.schema = schema;
+    }
+}
+exports.TypeGuardInvalidTypeError = TypeGuardInvalidTypeError;
+/** TypeGuard tests that values conform to a known TypeBox type specification */
+var TypeGuard;
+(function (TypeGuard) {
+    function IsObject(value) {
+        return typeof value === 'object' && value !== null && !Array.isArray(value);
+    }
+    function IsArray(value) {
+        return typeof value === 'object' && value !== null && Array.isArray(value);
+    }
+    function IsPattern(value) {
+        try {
+            new RegExp(value);
+            return true;
+        }
+        catch {
+            return false;
+        }
+    }
+    function IsControlCharacterFree(value) {
+        if (typeof value !== 'string')
+            return false;
+        for (let i = 0; i < value.length; i++) {
+            const code = value.charCodeAt(i);
+            if ((code >= 7 && code <= 13) || code === 27 || code === 127) {
+                return false;
+            }
+        }
+        return true;
+    }
+    function IsString(value) {
+        return typeof value === 'string';
+    }
+    function IsNumber(value) {
+        return typeof value === 'number';
+    }
+    function IsBoolean(value) {
+        return typeof value === 'boolean';
+    }
+    function IsOptionalNumber(value) {
+        return value === undefined || (value !== undefined && IsNumber(value));
+    }
+    function IsOptionalBoolean(value) {
+        return value === undefined || (value !== undefined && IsBoolean(value));
+    }
+    function IsOptionalString(value) {
+        return value === undefined || (value !== undefined && IsString(value));
+    }
+    function IsOptionalPattern(value) {
+        return value === undefined || (value !== undefined && IsString(value) && IsControlCharacterFree(value) && IsPattern(value));
+    }
+    function IsOptionalFormat(value) {
+        return value === undefined || (value !== undefined && IsString(value) && IsControlCharacterFree(value));
+    }
+    function IsOptionalSchema(value) {
+        return value === undefined || TSchema(value);
+    }
+    /** Returns true if the given schema is TAny */
+    function TAny(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Any' && IsOptionalString(schema.$id);
+    }
+    TypeGuard.TAny = TAny;
+    /** Returns true if the given schema is TArray */
+    function TArray(schema) {
+        return (IsObject(schema) &&
+            schema[Types.Kind] === 'Array' &&
+            schema.type === 'array' &&
+            IsOptionalString(schema.$id) &&
+            TSchema(schema.items) &&
+            IsOptionalNumber(schema.minItems) &&
+            IsOptionalNumber(schema.maxItems) &&
+            IsOptionalBoolean(schema.uniqueItems));
+    }
+    TypeGuard.TArray = TArray;
+    /** Returns true if the given schema is TBoolean */
+    function TBoolean(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Boolean' && schema.type === 'boolean' && IsOptionalString(schema.$id);
+    }
+    TypeGuard.TBoolean = TBoolean;
+    /** Returns true if the given schema is TConstructor */
+    function TConstructor(schema) {
+        if (!(IsObject(schema) && schema[Types.Kind] === 'Constructor' && schema.type === 'constructor' && IsOptionalString(schema.$id) && IsArray(schema.parameters) && TSchema(schema.returns))) {
+            return false;
+        }
+        for (const parameter of schema.parameters) {
+            if (!TSchema(parameter))
+                return false;
+        }
+        return true;
+    }
+    TypeGuard.TConstructor = TConstructor;
+    /** Returns true if the given schema is TFunction */
+    function TFunction(schema) {
+        if (!(IsObject(schema) && schema[Types.Kind] === 'Function' && schema.type === 'function' && IsOptionalString(schema.$id) && IsArray(schema.parameters) && TSchema(schema.returns))) {
+            return false;
+        }
+        for (const parameter of schema.parameters) {
+            if (!TSchema(parameter))
+                return false;
+        }
+        return true;
+    }
+    TypeGuard.TFunction = TFunction;
+    /** Returns true if the given schema is TInteger */
+    function TInteger(schema) {
+        return (IsObject(schema) &&
+            schema[Types.Kind] === 'Integer' &&
+            schema.type === 'integer' &&
+            IsOptionalString(schema.$id) &&
+            IsOptionalNumber(schema.multipleOf) &&
+            IsOptionalNumber(schema.minimum) &&
+            IsOptionalNumber(schema.maximum) &&
+            IsOptionalNumber(schema.exclusiveMinimum) &&
+            IsOptionalNumber(schema.exclusiveMaximum));
+    }
+    TypeGuard.TInteger = TInteger;
+    /** Returns true if the given schema is TLiteral */
+    function TLiteral(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Literal' && IsOptionalString(schema.$id) && (IsString(schema.const) || IsNumber(schema.const) || IsBoolean(schema.const));
+    }
+    TypeGuard.TLiteral = TLiteral;
+    /** Returns true if the given schema is TNever */
+    function TNever(schema) {
+        return (IsObject(schema) &&
+            schema[Types.Kind] === 'Never' &&
+            IsArray(schema.allOf) &&
+            schema.allOf.length === 2 &&
+            IsObject(schema.allOf[0]) &&
+            IsString(schema.allOf[0].type) &&
+            schema.allOf[0].type === 'boolean' &&
+            schema.allOf[0].const === false &&
+            IsObject(schema.allOf[1]) &&
+            IsString(schema.allOf[1].type) &&
+            schema.allOf[1].type === 'boolean' &&
+            schema.allOf[1].const === true);
+    }
+    TypeGuard.TNever = TNever;
+    /** Returns true if the given schema is TNull */
+    function TNull(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Null' && schema.type === 'null' && IsOptionalString(schema.$id);
+    }
+    TypeGuard.TNull = TNull;
+    /** Returns true if the given schema is TNumber */
+    function TNumber(schema) {
+        return (IsObject(schema) &&
+            schema[Types.Kind] === 'Number' &&
+            schema.type === 'number' &&
+            IsOptionalString(schema.$id) &&
+            IsOptionalNumber(schema.multipleOf) &&
+            IsOptionalNumber(schema.minimum) &&
+            IsOptionalNumber(schema.maximum) &&
+            IsOptionalNumber(schema.exclusiveMinimum) &&
+            IsOptionalNumber(schema.exclusiveMaximum));
+    }
+    TypeGuard.TNumber = TNumber;
+    /** Returns true if the given schema is TObject */
+    function TObject(schema) {
+        if (!(IsObject(schema) &&
+            schema[Types.Kind] === 'Object' &&
+            schema.type === 'object' &&
+            IsOptionalString(schema.$id) &&
+            IsObject(schema.properties) &&
+            (IsOptionalBoolean(schema.additionalProperties) || IsOptionalSchema(schema.additionalProperties)) &&
+            IsOptionalNumber(schema.minProperties) &&
+            IsOptionalNumber(schema.maxProperties))) {
+            return false;
+        }
+        for (const [key, value] of Object.entries(schema.properties)) {
+            if (!IsControlCharacterFree(key))
+                return false;
+            if (!TSchema(value))
+                return false;
+        }
+        return true;
+    }
+    TypeGuard.TObject = TObject;
+    /** Returns true if the given schema is TPromise */
+    function TPromise(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Promise' && schema.type === 'promise' && IsOptionalString(schema.$id) && TSchema(schema.item);
+    }
+    TypeGuard.TPromise = TPromise;
+    /** Returns true if the given schema is TRecord */
+    function TRecord(schema) {
+        if (!(IsObject(schema) && schema[Types.Kind] === 'Record' && schema.type === 'object' && IsOptionalString(schema.$id) && schema.additionalProperties === false && IsObject(schema.patternProperties))) {
+            return false;
+        }
+        const keys = Object.keys(schema.patternProperties);
+        if (keys.length !== 1) {
+            return false;
+        }
+        if (!IsPattern(keys[0])) {
+            return false;
+        }
+        if (!TSchema(schema.patternProperties[keys[0]])) {
+            return false;
+        }
+        return true;
+    }
+    TypeGuard.TRecord = TRecord;
+    /** Returns true if the given schema is TSelf */
+    function TSelf(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Self' && IsOptionalString(schema.$id) && IsString(schema.$ref);
+    }
+    TypeGuard.TSelf = TSelf;
+    /** Returns true if the given schema is TRef */
+    function TRef(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Ref' && IsOptionalString(schema.$id) && IsString(schema.$ref);
+    }
+    TypeGuard.TRef = TRef;
+    /** Returns true if the given schema is TString */
+    function TString(schema) {
+        return (IsObject(schema) &&
+            schema[Types.Kind] === 'String' &&
+            schema.type === 'string' &&
+            IsOptionalString(schema.$id) &&
+            IsOptionalNumber(schema.minLength) &&
+            IsOptionalNumber(schema.maxLength) &&
+            IsOptionalPattern(schema.pattern) &&
+            IsOptionalFormat(schema.format));
+    }
+    TypeGuard.TString = TString;
+    /** Returns true if the given schema is TTuple */
+    function TTuple(schema) {
+        if (!(IsObject(schema) && schema[Types.Kind] === 'Tuple' && schema.type === 'array' && IsOptionalString(schema.$id) && IsNumber(schema.minItems) && IsNumber(schema.maxItems) && schema.minItems === schema.maxItems)) {
+            return false;
+        }
+        if (schema.items === undefined && schema.additionalItems === undefined && schema.minItems === 0) {
+            return true;
+        }
+        if (!IsArray(schema.items)) {
+            return false;
+        }
+        for (const inner of schema.items) {
+            if (!TSchema(inner))
+                return false;
+        }
+        return true;
+    }
+    TypeGuard.TTuple = TTuple;
+    /** Returns true if the given schema is TUndefined */
+    function TUndefined(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Undefined' && schema.type === 'object' && IsOptionalString(schema.$id) && schema.specialized === 'Undefined';
+    }
+    TypeGuard.TUndefined = TUndefined;
+    /** Returns true if the given schema is TUnion */
+    function TUnion(schema) {
+        if (!(IsObject(schema) && schema[Types.Kind] === 'Union' && IsArray(schema.anyOf) && IsOptionalString(schema.$id))) {
+            return false;
+        }
+        for (const inner of schema.anyOf) {
+            if (!TSchema(inner))
+                return false;
+        }
+        return true;
+    }
+    TypeGuard.TUnion = TUnion;
+    /** Returns true if the given schema is TUint8Array */
+    function TUint8Array(schema) {
+        return (IsObject(schema) &&
+            schema[Types.Kind] === 'Uint8Array' &&
+            schema.type === 'object' &&
+            IsOptionalString(schema.$id) &&
+            schema.specialized === 'Uint8Array' &&
+            IsOptionalNumber(schema.minByteLength) &&
+            IsOptionalNumber(schema.maxByteLength));
+    }
+    TypeGuard.TUint8Array = TUint8Array;
+    /** Returns true if the given schema is TUnknown */
+    function TUnknown(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Unknown' && IsOptionalString(schema.$id);
+    }
+    TypeGuard.TUnknown = TUnknown;
+    /** Returns true if the given schema is TVoid */
+    function TVoid(schema) {
+        return IsObject(schema) && schema[Types.Kind] === 'Void' && schema.type === 'null' && IsOptionalString(schema.$id);
+    }
+    TypeGuard.TVoid = TVoid;
+    /** Returns true if the given schema is TSchema */
+    function TSchema(schema) {
+        return (TAny(schema) ||
+            TArray(schema) ||
+            TBoolean(schema) ||
+            TConstructor(schema) ||
+            TFunction(schema) ||
+            TInteger(schema) ||
+            TLiteral(schema) ||
+            TNever(schema) ||
+            TNull(schema) ||
+            TNumber(schema) ||
+            TObject(schema) ||
+            TPromise(schema) ||
+            TRecord(schema) ||
+            TSelf(schema) ||
+            TRef(schema) ||
+            TString(schema) ||
+            TTuple(schema) ||
+            TUndefined(schema) ||
+            TUnion(schema) ||
+            TUint8Array(schema) ||
+            TUnknown(schema) ||
+            TVoid(schema));
+    }
+    TypeGuard.TSchema = TSchema;
+    /** Asserts if this schema and associated references are valid. */
+    function Assert(schema, references = []) {
+        if (!TSchema(schema))
+            throw new TypeGuardInvalidTypeError(schema);
+        for (const schema of references) {
+            if (!TSchema(schema))
+                throw new TypeGuardInvalidTypeError(schema);
+        }
+    }
+    TypeGuard.Assert = Assert;
+})(TypeGuard = exports.TypeGuard || (exports.TypeGuard = {}));
Index: frontend/node_modules/@sinclair/typebox/guard/index.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/guard/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/guard/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1 @@
+export * from './guard';
Index: frontend/node_modules/@sinclair/typebox/guard/index.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/guard/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/guard/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,44 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/guards
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./guard"), exports);
Index: frontend/node_modules/@sinclair/typebox/license
===================================================================
--- frontend/node_modules/@sinclair/typebox/license	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/license	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,23 @@
+TypeBox: JSON Schema Type Builder with Static Type Resolution for TypeScript 
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
Index: frontend/node_modules/@sinclair/typebox/package.json
===================================================================
--- frontend/node_modules/@sinclair/typebox/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+{
+  "name": "@sinclair/typebox",
+  "version": "0.24.51",
+  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
+  "keywords": [
+    "typescript",
+    "json-schema",
+    "validate",
+    "typecheck"
+  ],
+  "author": "sinclairzx81",
+  "license": "MIT",
+  "main": "./typebox.js",
+  "types": "./typebox.d.ts",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/sinclairzx81/typebox"
+  },
+  "scripts": {
+    "clean": "hammer task clean",
+    "format": "hammer task format",
+    "start": "hammer task start",
+    "test": "hammer task test",
+    "benchmark": "hammer task benchmark",
+    "build": "hammer task build",
+    "publish": "hammer task publish"
+  },
+  "devDependencies": {
+    "@sinclair/hammer": "^0.17.1",
+    "@types/chai": "^4.3.3",
+    "@types/mocha": "^9.1.1",
+    "@types/node": "^18.7.13",
+    "ajv": "^8.11.0",
+    "ajv-formats": "^2.1.1",
+    "chai": "^4.3.6",
+    "mocha": "^9.2.2",
+    "prettier": "^2.7.1",
+    "typescript": "^4.8.2"
+  }
+}
Index: frontend/node_modules/@sinclair/typebox/readme.md
===================================================================
--- frontend/node_modules/@sinclair/typebox/readme.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/readme.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1152 @@
+<div align='center'>
+
+<h1>TypeBox</h1>
+
+<p>JSON Schema Type Builder with Static Type Resolution for TypeScript</p>
+	
+<img src="https://github.com/sinclairzx81/typebox/blob/master/typebox.png?raw=true" />
+
+<br />
+<br />
+
+[![npm version](https://badge.fury.io/js/%40sinclair%2Ftypebox.svg)](https://badge.fury.io/js/%40sinclair%2Ftypebox)
+[![Downloads](https://img.shields.io/npm/dm/%40sinclair%2Ftypebox.svg)](https://www.npmjs.com/package/%40sinclair%2Ftypebox)
+[![GitHub CI](https://github.com/sinclairzx81/typebox/workflows/GitHub%20CI/badge.svg)](https://github.com/sinclairzx81/typebox/actions)
+
+</div>
+
+<a name="Install"></a>
+
+## Install
+
+Node
+
+```bash
+$ npm install @sinclair/typebox --save
+```
+
+Deno and ESM
+
+```typescript
+import { Static, Type } from 'https://esm.sh/@sinclair/typebox'
+```
+
+## Example
+
+```typescript
+import { Static, Type } from '@sinclair/typebox'
+
+const T = Type.String()     // const T = { type: 'string' }
+
+type T = Static<typeof T>   // type T = string
+```
+
+<a name="Overview"></a>
+
+## Overview
+
+TypeBox is a type builder library that creates in-memory JSON Schema objects that can be statically inferred as TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox enables one to create a unified type that can be statically checked by TypeScript and runtime asserted using standard JSON Schema validation.
+
+TypeBox is designed to enable JSON schema to compose with the same flexibility as TypeScript's type system. It can be used either as a simple tool to build up complex schemas or integrated into REST and RPC services to help validate data received over the wire. 
+
+License MIT
+
+## Contents
+- [Install](#install)
+- [Overview](#overview)
+- [Usage](#usage)
+- [Types](#types)
+  - [Standard](#types-standard)
+  - [Modifiers](#types-modifiers)
+  - [Options](#types-options)
+  - [Extended](#types-extended)
+  - [Reference](#types-reference)
+  - [Recursive](#types-recursive)
+  - [Generic](#types-generic)
+  - [Conditional](#types-conditional)
+  - [Unsafe](#types-unsafe)
+  - [Guards](#types-guards)
+  - [Strict](#types-strict)
+- [Values](#values)
+  - [Create](#values-create)
+  - [Clone](#values-clone)
+  - [Check](#values-check)
+  - [Cast](#values-cast)
+  - [Equal](#values-equal)
+  - [Diff](#values-diff)
+  - [Patch](#values-patch)
+  - [Errors](#values-errors)
+  - [Pointer](#values-pointer)
+- [TypeCheck](#typecheck)
+  - [Ajv](#typecheck-ajv)
+  - [Compiler](#typecheck-compiler)
+  - [Formats](#typecheck-formats)
+- [Benchmark](#benchmark)
+  - [Compile](#benchmark-compile)
+  - [Validate](#benchmark-validate)
+  - [Compression](#benchmark-compression)
+- [Contribute](#contribute)
+
+<a name="Example"></a>
+
+## Usage
+
+The following demonstrates TypeBox's general usage.
+
+```typescript
+
+import { Static, Type } from '@sinclair/typebox'
+
+//--------------------------------------------------------------------------------------------
+//
+// Let's say you have the following type ...
+//
+//--------------------------------------------------------------------------------------------
+
+type T = {
+  id: string,
+  name: string,
+  timestamp: number
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// ... you can express this type in the following way.
+//
+//--------------------------------------------------------------------------------------------
+
+const T = Type.Object({                              // const T = {
+  id: Type.String(),                                 //   type: 'object',
+  name: Type.String(),                               //   properties: { 
+  timestamp: Type.Integer()                          //     id: { 
+})                                                   //       type: 'string' 
+                                                     //     },
+                                                     //     name: { 
+                                                     //       type: 'string' 
+                                                     //     },
+                                                     //     timestamp: { 
+                                                     //       type: 'integer' 
+                                                     //     }
+                                                     //   }, 
+                                                     //   required: [
+                                                     //     'id',
+                                                     //     'name',
+                                                     //     'timestamp'
+                                                     //   ]
+                                                     // } 
+
+//--------------------------------------------------------------------------------------------
+//
+// ... then infer back to the original static type this way.
+//
+//--------------------------------------------------------------------------------------------
+
+type T = Static<typeof T>                            // type T = {
+                                                     //   id: string,
+                                                     //   name: string,
+                                                     //   timestamp: number
+                                                     // }
+
+//--------------------------------------------------------------------------------------------
+//
+// ... then use the type both as JSON schema and as a TypeScript type.
+//
+//--------------------------------------------------------------------------------------------
+
+function receive(value: T) {                         // ... as a Type
+
+  if(JSON.validate(T, value)) {                      // ... as a Schema
+  
+    // ok...
+  }
+}
+```
+
+<a name='types'></a>
+
+## Types
+
+TypeBox provides a set of functions that allow you to compose JSON Schema similar to how you would compose static types with TypeScript. Each function creates a JSON schema fragment which can compose into more complex types. The schemas produced by TypeBox can be passed directly to any JSON Schema compliant validator, or used to reflect runtime metadata for a type.
+
+<a name='types-standard'></a>
+
+### Standard
+
+The following table lists the standard TypeBox types.
+
+```typescript
+┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
+│ TypeBox                        │ TypeScript                  │ JSON Schema                    │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Any()           │ type T = any                │ const T = { }                  │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Unknown()       │ type T = unknown            │ const T = { }                  │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.String()        │ type T = string             │ const T = {                    │
+│                                │                             │   type: 'string'               │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Number()        │ type T = number             │ const T = {                    │
+│                                │                             │   type: 'number'               │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Integer()       │ type T = number             │ const T = {                    │
+│                                │                             │   type: 'integer'              │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Boolean()       │ type T = boolean            │ const T = {                    │
+│                                │                             │   type: 'boolean'              │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Null()          │ type T = null               │ const T = {                    │
+│                                │                             │    type: 'null'                │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.RegEx(/foo/)    │ type T = string             │ const T = {                    │
+│                                │                             │    type: 'string',             │
+│                                │                             │    pattern: 'foo'              │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Literal(42)     │ type T = 42                 │ const T = {                    │
+│                                │                             │    const: 42,                  │
+│                                │                             │    type: 'number'              │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Array(          │ type T = number[]           │ const T = {                    │
+│   Type.Number()                │                             │   type: 'array',               │
+│ )                              │                             │   items: {                     │
+│                                │                             │     type: 'number'             │
+│                                │                             │   }                            │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Object({        │ type T = {                  │ const T = {                    │
+│   x: Type.Number(),            │   x: number,                │   type: 'object',              │
+│   y: Type.Number()             │   y: number                 │   properties: {                │
+│ })                             │ }                           │      x: {                      │
+│                                │                             │        type: 'number'          │
+│                                │                             │      },                        │
+│                                │                             │      y: {                      │
+│                                │                             │        type: 'number'          │
+│                                │                             │      }                         │
+│                                │                             │   },                           │
+│                                │                             │   required: ['x', 'y']         │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Tuple([         │ type T = [number, number]   │ const T = {                    │
+│   Type.Number(),               │                             │   type: 'array',               │
+│   Type.Number()                │                             │   items: [{                    │
+│ ])                             │                             │      type: 'number'            │
+│                                │                             │    }, {                        │
+│                                │                             │      type: 'number'            │
+│                                │                             │    }],                         │
+│                                │                             │    additionalItems: false,     │
+│                                │                             │    minItems: 2,                │
+│                                │                             │    maxItems: 2                 │
+│                                │                             │ }                              │
+│                                │                             │                                │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ enum Foo {                     │ enum Foo {                  │ const T = {                    │
+│   A,                           │   A,                        │   anyOf: [{                    │
+│   B                            │   B                         │     type: 'number',            │
+│ }                              │ }                           │     const: 0                   │
+│                                │                             │   }, {                         │
+│ const T = Type.Enum(Foo)       │ type T = Foo                │     type: 'number',            │
+│                                │                             │     const: 1                   │
+│                                │                             │   }]                           │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.KeyOf(          │ type T = keyof {            │ const T = {                    │
+│   Type.Object({                │   x: number,                │   anyOf: [{                    │
+│     x: Type.Number(),          │   y: number                 │     type: 'string',            │
+│     y: Type.Number()           │ }                           │     const: 'x'                 │
+│   })                           │                             │   }, {                         │
+│ )                              │                             │     type: 'string',            │
+│                                │                             │     const: 'y'                 │
+│                                │                             │   }]                           │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Union([         │ type T = string | number    │ const T = {                    │
+│   Type.String(),               │                             │   anyOf: [{                    │
+│   Type.Number()                │                             │      type: 'string'            │
+│ ])                             │                             │   }, {                         │
+│                                │                             │      type: 'number'            │
+│                                │                             │   }]                           │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Intersect([     │ type T = {                  │ const T = {                    │
+│   Type.Object({                │   x: number                 │   type: 'object',              │
+│     x: Type.Number()           │ } & {                       │   properties: {                │
+│   }),                          │   y: number                 │     x: {                       │
+│   Type.Object({                │ }                           │       type: 'number'           │
+│     y: Type.Number()           │                             │     },                         │
+│   })                           │                             │     y: {                       │
+│ ])                             │                             │       type: 'number'           │
+│                                │                             │     }                          │
+│                                │                             │   },                           │
+│                                │                             │   required: ['x', 'y']         │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Never()         │ type T = never              │ const T = {                    │
+│                                │                             │   allOf: [{                    │
+│                                │                             │     type: 'boolean',           │
+│                                │                             │     const: false               │
+│                                │                             │   }, {                         │
+│                                │                             │     type: 'boolean',           │
+│                                │                             │     const: true                │
+│                                │                             │   }]                           │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Record(         │ type T = Record<            │ const T = {                    │
+│   Type.String(),               │   string,                   │   type: 'object',              │
+│   Type.Number()                │   number,                   │   patternProperties: {         │
+│ )                              │ >                           │     '^.*$': {                  │
+│                                │                             │       type: 'number'           │
+│                                │                             │     }                          │
+│                                │                             │   }                            │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Partial(        │ type T = Partial<{          │ const T = {                    │
+│   Type.Object({                │   x: number,                │   type: 'object',              │
+│     x: Type.Number(),          │   y: number                 │   properties: {                │
+│     y: Type.Number()           | }>                          │     x: {                       │
+│   })                           │                             │       type: 'number'           │
+│ )                              │                             │     },                         │
+│                                │                             │     y: {                       │
+│                                │                             │       type: 'number'           │
+│                                │                             │     }                          │
+│                                │                             │   }                            │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Required(       │ type T = Required<{         │ const T = {                    │
+│   Type.Object({                │   x?: number,               │   type: 'object',              │
+│     x: Type.Optional(          │   y?: number                │   properties: {                │
+│       Type.Number()            | }>                          │     x: {                       │
+│     ),                         │                             │       type: 'number'           │
+│     y: Type.Optional(          │                             │     },                         │
+│       Type.Number()            │                             │     y: {                       │
+│     )                          │                             │       type: 'number'           │
+│   })                           │                             │     }                          │
+│ )                              │                             │   },                           │
+│                                │                             │   required: ['x', 'y']         │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Pick(           │ type T = Pick<{             │ const T = {                    │
+│   Type.Object({                │   x: number,                │   type: 'object',              │
+│     x: Type.Number(),          │   y: number                 │   properties: {                │
+│     y: Type.Number()           | }, 'x'>                     │     x: {                       │
+│   }), ['x']                    │                             │       type: 'number'           │
+│ )                              │                             │     }                          │
+│                                │                             │   },                           │
+│                                │                             │   required: ['x']              │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Omit(           │ type T = Omit<{             │ const T = {                    │
+│   Type.Object({                │   x: number,                │   type: 'object',              │
+│     x: Type.Number(),          │   y: number                 │   properties: {                │
+│     y: Type.Number()           | }, 'x'>                     │     y: {                       │
+│   }), ['x']                    │                             │       type: 'number'           │
+│ )                              │                             │     }                          │
+│                                │                             │   },                           │
+│                                │                             │   required: ['y']              │
+│                                │                             │ }                              │
+│                                │                             │                                │
+└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
+```
+
+<a name='types-modifiers'></a>
+
+### Modifiers
+
+TypeBox provides modifiers that can be applied to an objects properties. This allows for `optional` and `readonly` to be applied to that property. The following table illustates how they map between TypeScript and JSON Schema.
+
+```typescript
+┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
+│ TypeBox                        │ TypeScript                  │ JSON Schema                    │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Object({        │ type T = {                  │ const T = {                    │
+│   name: Type.Optional(         │   name?: string             │   type: 'object',              │
+│     Type.String()              │ }                           │   properties: {                │
+│   )                            │                             │      name: {                   │
+│ })  	                         │                             │        type: 'string'          │
+│                                │                             │      }                         │
+│                                │                             │   }                            │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Object({        │ type T = {                  │ const T = {                    │
+│   name: Type.Readonly(         │   readonly name: string     │   type: 'object',              │
+│     Type.String()              │ }                           │   properties: {                │
+│   )                            │                             │     name: {                    │
+│ })  	                         │                             │       type: 'string'           │
+│                                │                             │     }                          │
+│                                │                             │   },                           │
+│                                │                             │   required: ['name']           │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Object({        │ type T = {                  │ const T = {                    │
+│   name: Type.ReadonlyOptional( │   readonly name?: string    │   type: 'object',              │
+│     Type.String()              │ }                           │   properties: {                │
+│   )                            │                             │     name: {                    │
+│ })  	                         │                             │       type: 'string'           │
+│                                │                             │     }                          │
+│                                │                             │   }                            │
+│                                │                             │ }                              │
+│                                │                             │                                │
+└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
+```
+
+<a name='types-options'></a>
+
+### Options
+
+You can pass additional JSON schema options on the last argument of any given type. The following are some examples.
+
+```typescript
+// string must be an email
+const T = Type.String({ format: 'email' })
+
+// number must be a multiple of 2
+const T = Type.Number({ multipleOf: 2 })
+
+// array must have at least 5 integer values
+const T = Type.Array(Type.Integer(), { minItems: 5 })
+```
+
+<a name='types-extended'></a>
+
+### Extended
+
+In addition to JSON schema types, TypeBox provides several extended types that allow for the composition of `function` and `constructor` types. These additional types are not valid JSON Schema and will not validate using typical JSON Schema validation. However, these types can be used to frame JSON schema and describe callable interfaces that may receive JSON validated data. These types are as follows.
+
+```typescript
+┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
+│ TypeBox                        │ TypeScript                  │ Extended Schema                │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Constructor([   │ type T = new (              │ const T = {                    │
+│   Type.String(),               │  arg0: string,              │   type: 'constructor'          │
+│   Type.Number()                │  arg1: number               │   parameters: [{               │
+│ ], Type.Boolean())             │ ) => boolean                │     type: 'string'             │
+│                                │                             │   }, {                         │
+│                                │                             │     type: 'number'             │
+│                                │                             │   }],                          │
+│                                │                             │   return: {                    │
+│                                │                             │     type: 'boolean'            │
+│                                │                             │   }                            │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Function([      │ type T = (                  │ const T = {                    │
+|   Type.String(),               │  arg0: string,              │   type : 'function',           │
+│   Type.Number()                │  arg1: number               │   parameters: [{               │
+│ ], Type.Boolean())             │ ) => boolean                │     type: 'string'             │
+│                                │                             │   }, {                         │
+│                                │                             │     type: 'number'             │
+│                                │                             │   }],                          │
+│                                │                             │   return: {                    │
+│                                │                             │     type: 'boolean'            │
+│                                │                             │   }                            │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Uint8Array()    │ type T = Uint8Array         │ const T = {                    │
+│                                │                             │   type: 'object',              │
+│                                │                             │   specialized: 'Uint8Array'    │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Promise(        │ type T = Promise<string>    │ const T = {                    │
+│   Type.String()                │                             │   type: 'promise',             │
+│ )                              │                             │   item: {                      │
+│                                │                             │     type: 'string'             │
+│                                │                             │   }                            │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Undefined()     │ type T = undefined          │ const T = {                    │
+│                                │                             │   type: 'object',              │
+│                                │                             │   specialized: 'Undefined'     │
+│                                │                             │ }                              │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Type.Void()          │ type T = void               │ const T = {                    │
+│                                │                             │   type: 'null'                 │
+│                                │                             │ }                              │
+│                                │                             │                                │
+└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
+```
+
+<a name='types-reference'></a>
+
+### Reference
+
+Use `Type.Ref(...)` to create referenced types. The target type must specify an `$id`.
+
+```typescript
+const T = Type.String({ $id: 'T' })                  // const T = {
+                                                     //    $id: 'T',
+                                                     //    type: 'string'
+                                                     // }
+                                             
+const R = Type.Ref(T)                                // const R = {
+                                                     //    $ref: 'T'
+                                                     // }
+```
+
+<a name='types-recursive'></a>
+
+### Recursive
+
+Use `Type.Recursive(...)` to create recursive types.
+
+```typescript
+const Node = Type.Recursive(Node => Type.Object({    // const Node = {
+  id: Type.String(),                                 //   $id: 'Node',
+  nodes: Type.Array(Node)                            //   type: 'object',
+}), { $id: 'Node' })                                 //   properties: {
+                                                     //     id: {
+                                                     //       type: 'string'
+                                                     //     },
+                                                     //     nodes: {
+                                                     //       type: 'array',
+                                                     //       items: {
+                                                     //         $ref: 'Node'
+                                                     //       }
+                                                     //     }
+                                                     //   },
+                                                     //   required: [
+                                                     //     'id',
+                                                     //     'nodes'
+                                                     //   ]
+                                                     // }
+
+type Node = Static<typeof Node>                      // type Node = {
+                                                     //   id: string
+                                                     //   nodes: Node[]
+                                                     // }
+
+function test(node: Node) {
+  const id = node.nodes[0].nodes[0]                  // id is string
+                 .nodes[0].nodes[0]
+                 .id
+}
+```
+
+<a name='types-generic'></a>
+
+### Generic
+
+Use functions to create generic types. The following creates a generic `Nullable<T>` type. 
+
+```typescript
+import { Type, Static, TSchema } from '@sinclair/typebox'
+
+const Nullable = <T extends TSchema>(type: T) => Type.Union([type, Type.Null()])
+
+const T = Nullable(Type.String())                    // const T = {
+                                                     //   anyOf: [{
+                                                     //     type: 'string'
+                                                     //   }, {
+                                                     //     type: 'null'
+                                                     //   }]
+                                                     // }
+
+type T = Static<typeof T>                            // type T = string | null
+
+const U = Nullable(Type.Number())                    // const U = {
+                                                     //   anyOf: [{
+                                                     //     type: 'number'
+                                                     //   }, {
+                                                     //     type: 'null'
+                                                     //   }]
+                                                     // }
+
+type U = Static<typeof U>                            // type U = number | null
+```
+
+<a name='types-conditional'></a>
+
+### Conditional
+
+Use the conditional module to create [Conditional Types](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html). This module implements TypeScript's structural equivalence checks to enable TypeBox types to be conditionally inferred at runtime. This module also provides the [Extract](https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union) and [Exclude](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers) utility types which are expressed as conditional types in TypeScript. 
+
+The conditional module is provided as an optional import.
+
+```typescript
+import { Conditional } from '@sinclair/typebox/conditional'
+```
+The following table shows the TypeBox mappings between TypeScript and JSON schema.
+
+```typescript
+┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
+│ TypeBox                        │ TypeScript                  │ JSON Schema                    │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Conditional.Extends( │ type T =                    │ const T = {                    │
+│   Type.String(),               │  string extends number      │   const: false,                │
+│   Type.Number(),               │  true : false               │   type: 'boolean'              │
+│   Type.Literal(true),          │                             │ }                              │
+│   Type.Literal(false)          │                             │                                │
+│ )                              │                             │                                │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Conditional.Extract( │ type T = Extract<           │ const T = {                    │
+│   Type.Union([                 │   'a' | 'b' | 'c',          │   anyOf: [{                    │
+│     Type.Literal('a'),         │   'a' | 'f'                 │     const: 'a'                 │
+│     Type.Literal('b'),         │ >                           │     type: 'string'             │
+│     Type.Literal('c')          │                             │   }]                           │
+│   ]),                          │                             │ }                              │
+│   Type.Union([                 │                             │                                │
+│     Type.Literal('a'),         │                             │                                │
+│     Type.Literal('f')          │                             │                                │
+│   ])                           │                             │                                │
+│ )                              │                             │                                │
+│                                │                             │                                │
+├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
+│ const T = Conditional.Exclude( │ type T = Exclude<           │ const T = {                    │
+│   Type.Union([                 │   'a' | 'b' | 'c',          │   anyOf: [{                    │
+│     Type.Literal('a'),         │   'a'                       │     const: 'b',                │
+│     Type.Literal('b'),         │ >                           │     type: 'string'             │
+│     Type.Literal('c')          │                             │   }, {                         │
+│   ]),                          │                             │     const: 'c',                │
+│   Type.Union([                 │                             │     type: 'string'             │
+│     Type.Literal('a')          │                             │   }]                           │
+│   ])                           │                             │ }                              │
+│ )                              │                             │                                │
+│                                │                             │                                │
+└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
+```
+
+<a name='types-unsafe'></a>
+
+### Unsafe
+
+Use `Type.Unsafe(...)` to create custom schemas with user defined inference rules.
+
+```typescript
+const T = Type.Unsafe<string>({ type: 'number' })    // const T = {
+                                                     //   type: 'number'
+                                                     // }
+
+type T = Static<typeof T>                            // type T = string
+```
+
+This function can be used to create custom schemas for validators that require specific schema representations. An example of this might be OpenAPI's `nullable` and `enum` schemas which are not provided by TypeBox. The following demonstrates using `Type.Unsafe(...)` to create these types.
+
+```typescript
+import { Type, Static, TSchema } from '@sinclair/typebox'
+
+//--------------------------------------------------------------------------------------------
+//
+// Nullable<T>
+//
+//--------------------------------------------------------------------------------------------
+
+function Nullable<T extends TSchema>(schema: T) {
+  return Type.Unsafe<Static<T> | null>({ ...schema, nullable: true })
+}
+
+const T = Nullable(Type.String())                    // const T = {
+                                                     //   type: 'string',
+                                                     //   nullable: true
+                                                     // }
+
+type T = Static<typeof T>                            // type T = string | null
+
+
+//--------------------------------------------------------------------------------------------
+//
+// StringEnum<string[]>
+//
+//--------------------------------------------------------------------------------------------
+
+function StringEnum<T extends string[]>(values: [...T]) {
+  return Type.Unsafe<T[number]>({ type: 'string', enum: values })
+}
+
+const T = StringEnum(['A', 'B', 'C'])                // const T = {
+                                                     //   enum: ['A', 'B', 'C']
+                                                     // }
+
+type T = Static<typeof T>                            // type T = 'A' | 'B' | 'C'
+```
+
+<a name='types-guards'></a>
+
+### Guards
+
+Use the guard module to test if values are TypeBox types.
+
+```typescript
+import { TypeGuard } from '@sinclair/typebox/guard'
+
+const T = Type.String()
+
+if(TypeGuard.TString(T)) {
+    
+  // T is TString
+}
+```
+
+<a name='types-strict'></a>
+
+### Strict
+
+TypeBox schemas contain the `Kind` and `Modifier` symbol properties. These properties are provided to enable runtime type reflection on schemas, as well as helping TypeBox internally compose types. These properties are not strictly valid JSON schema; so in some cases it may be desirable to omit them. TypeBox provides a `Type.Strict()` function that will omit these properties if necessary.
+
+```typescript
+const T = Type.Object({                              // const T = {
+  name: Type.Optional(Type.String())                 //   [Kind]: 'Object',
+})                                                   //   type: 'object',
+                                                     //   properties: {
+                                                     //     name: {
+                                                     //       [Kind]: 'String',
+                                                     //       type: 'string',
+                                                     //       [Modifier]: 'Optional'
+                                                     //     }
+                                                     //   }
+                                                     // }
+
+const U = Type.Strict(T)                             // const U = {
+                                                     //   type: 'object', 
+                                                     //   properties: { 
+                                                     //     name: { 
+                                                     //       type: 'string' 
+                                                     //     } 
+                                                     //   } 
+                                                     // }
+```
+
+<a name='values'></a>
+
+## Values
+
+TypeBox includes an optional values module that can be used to perform common operations on JavaScript values. This module enables one to create, check and cast values from types. It also provides functionality to check equality, clone and diff and patch JavaScript values. The value module is provided as an optional import.
+
+```typescript
+import { Value } from '@sinclair/typebox/value'
+```
+
+<a name='values-create'></a>
+
+### Create
+
+Use the Create function to create a value from a TypeBox type. TypeBox will use default values if specified.
+
+```typescript
+const T = Type.Object({ x: Type.Number(), y: Type.Number({ default: 42 }) })
+
+const A = Value.Create(T)                            // const A = { x: 0, y: 42 }
+```
+
+<a name='values-clone'></a>
+
+### Clone
+
+Use the Clone function to deeply clone a value
+
+```typescript
+const A = Value.Clone({ x: 1, y: 2, z: 3 })          // const A = { x: 1, y: 2, z: 3 }
+```
+
+<a name='values-check'></a>
+
+### Check
+
+Use the Check function to type check a value
+
+```typescript
+const T = Type.Object({ x: Type.Number() })
+
+const R = Value.Check(T, { x: 1 })                   // const R = true
+```
+
+<a name='values-cast'></a>
+
+### Cast
+
+Use the Cast function to cast a value into a type. The cast function will retain as much information as possible from the original value.
+
+```typescript
+const T = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false })
+
+const X = Value.Cast(T, null)                        // const X = { x: 0, y: 0 }
+
+const Y = Value.Cast(T, { x: 1 })                    // const Y = { x: 1, y: 0 }
+
+const Z = Value.Cast(T, { x: 1, y: 2, z: 3 })        // const Z = { x: 1, y: 2 }
+```
+
+<a name='values-equal'></a>
+
+### Equal
+
+Use the Equal function to deeply check for value equality.
+
+```typescript
+const R = Value.Equal(                               // const R = true
+  { x: 1, y: 2, z: 3 },
+  { x: 1, y: 2, z: 3 }
+)
+```
+
+<a name='values-diff'></a>
+
+### Diff
+
+Use the Diff function to produce a sequence of edits to transform one value into another.
+
+```typescript
+const E = Value.Diff<any>(                          // const E = [
+  { x: 1, y: 2, z: 3 },                             //   { type: 'update', path: '/y', value: 4 },
+  { y: 4, z: 5, w: 6 }                              //   { type: 'update', path: '/z', value: 5 },
+)                                                   //   { type: 'insert', path: '/w', value: 6 },
+                                                    //   { type: 'delete', path: '/x' }
+                                                    // ]
+```
+
+<a name='values-patch'></a>
+
+### Patch
+
+Use the Patch function to apply edits
+
+```typescript
+const A = { x: 1, y: 2 }
+
+const B = { x: 3 }
+
+const E = Value.Diff<any>(A, B)                      // const E = [
+                                                     //   { type: 'update', path: '/x', value: 3 },
+                                                     //   { type: 'delete', path: '/y' }
+                                                     // ]
+
+const C = Value.Patch<any>(A, E)                     // const C = { x: 3 }
+```
+
+
+<a name='values-errors'></a>
+
+### Errors
+
+Use the Errors function enumerate validation errors.
+
+```typescript
+const T = Type.Object({ x: Type.Number(), y: Type.Number() })
+
+const R = [...Value.Errors(T, { x: '42' })]          // const R = [{
+                                                     //   schema: { type: 'number' },
+                                                     //   path: '/x',
+                                                     //   value: '42',
+                                                     //   message: 'Expected number'
+                                                     // }, {
+                                                     //   schema: { type: 'number' },
+                                                     //   path: '/y',
+                                                     //   value: undefined,
+                                                     //   message: 'Expected number'
+                                                     // }]
+```
+
+<a name='values-pointer'></a>
+
+### Pointer
+
+Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) Json Pointers.
+
+```typescript
+import { ValuePointer } from '@sinclair/typebox/value'
+
+const A = { x: 0, y: 0, z: 0 }
+
+ValuePointer.Set(A, '/x', 1)                         // const A = { x: 1, y: 0, z: 0 }
+ValuePointer.Set(A, '/y', 1)                         // const A = { x: 1, y: 1, z: 0 }
+ValuePointer.Set(A, '/z', 1)                         // const A = { x: 1, y: 1, z: 1 }
+```
+<a name='typecheck'></a>
+
+## TypeCheck
+
+TypeBox is written to target JSON Schema Draft 6 and can be used with any Draft 6 compliant validator. TypeBox is developed and tested against Ajv and can be used in any application already making use of this validator. Additionally, TypeBox also provides an optional type compiler that can be used to attain improved compilation and validation performance for certain application types.
+
+<a name='typecheck-ajv'></a>
+
+### Ajv
+
+The following example shows setting up Ajv to work with TypeBox. 
+
+```bash
+$ npm install ajv ajv-formats --save
+```
+
+```typescript
+import { Type }   from '@sinclair/typebox'
+import addFormats from 'ajv-formats'
+import Ajv        from 'ajv'
+
+//--------------------------------------------------------------------------------------------
+//
+// Setup Ajv validator with the following options and formats
+//
+//--------------------------------------------------------------------------------------------
+
+const ajv = addFormats(new Ajv({}), [
+  'date-time', 
+  'time', 
+  'date', 
+  'email',  
+  'hostname', 
+  'ipv4', 
+  'ipv6', 
+  'uri', 
+  'uri-reference', 
+  'uuid',
+  'uri-template', 
+  'json-pointer', 
+  'relative-json-pointer', 
+  'regex'
+])
+
+//--------------------------------------------------------------------------------------------
+//
+// Create a TypeBox type
+//
+//--------------------------------------------------------------------------------------------
+
+const T = Type.Object({
+  x: Type.Number(),
+  y: Type.Number(),
+  z: Type.Number()
+})
+
+//--------------------------------------------------------------------------------------------
+//
+// Validate Data
+//
+//--------------------------------------------------------------------------------------------
+
+const R = ajv.validate(T, { x: 1, y: 2, z: 3 })      // const R = true
+```
+
+<a name='typecheck-compiler'></a>
+
+### Compiler
+
+TypeBox provides an optional high performance just-in-time (JIT) compiler and type checker that can be used in applications that require extremely fast validation. Note that this compiler is optimized for TypeBox types only where the schematics are known in advance. If defining custom types with `Type.Unsafe<T>` please consider Ajv.
+
+The compiler module is provided as an optional import.
+
+```typescript
+import { TypeCompiler } from '@sinclair/typebox/compiler'
+```
+
+Use the `Compile(...)` function to compile a type.
+
+```typescript
+const C = TypeCompiler.Compile(Type.Object({         // const C: TypeCheck<TObject<{
+  x: Type.Number(),                                  //     x: TNumber;
+  y: Type.Number(),                                  //     y: TNumber;
+  z: Type.Number()                                   //     z: TNumber;
+}))                                                  // }>>
+
+const R = C.Check({ x: 1, y: 2, z: 3 })              // const R = true
+```
+
+Validation errors can be read with the `Errors(...)` function.
+
+```typescript
+const C = TypeCompiler.Compile(Type.Object({         // const C: TypeCheck<TObject<{
+  x: Type.Number(),                                  //     x: TNumber;
+  y: Type.Number(),                                  //     y: TNumber;
+  z: Type.Number()                                   //     z: TNumber;
+}))                                                  // }>>
+
+const value = { }
+
+const errors = [...C.Errors(value)]                  // const errors = [{
+                                                     //   schema: { type: 'number' },
+                                                     //   path: '/x',
+                                                     //   value: undefined,
+                                                     //   message: 'Expected number'
+                                                     // }, {
+                                                     //   schema: { type: 'number' },
+                                                     //   path: '/y',
+                                                     //   value: undefined,
+                                                     //   message: 'Expected number'
+                                                     // }, {
+                                                     //   schema: { type: 'number' },
+                                                     //   path: '/z',
+                                                     //   value: undefined,
+                                                     //   message: 'Expected number'
+                                                     // }]
+```
+
+Compiled routines can be inspected with the `.Code()` function.
+
+```typescript
+const C = TypeCompiler.Compile(Type.String())        // const C: TypeCheck<TString>
+
+console.log(C.Code())                                // return function check(value) {
+                                                     //   return (
+                                                     //     (typeof value === 'string')
+                                                     //   )
+                                                     // }
+```
+
+<a name='typecheck-formats'></a>
+
+### Formats
+
+Use the format module to create user defined string formats. The format module is used by the Value and TypeCompiler modules only. If using Ajv, please refer to the official Ajv format documentation located [here](https://ajv.js.org/guide/formats.html).
+
+The format module is an optional import.
+
+```typescript
+import { Format } from '@sinclair/typebox/format'
+```
+
+The following creates a `palindrome` string format.
+
+```typescript
+Format.Set('palindrome', value => value === value.split('').reverse().join(''))
+```
+
+Once set, this format can then be used by the TypeCompiler and Value modules.
+
+```typescript
+const T = Type.String({ format: 'palindrome' })
+
+const A = TypeCompiler.Compile(T).Check('engine')    // const A = false
+
+const B = Value.Check(T, 'kayak')                    // const B = true
+```
+
+<a name='benchmark'></a>
+
+## Benchmark
+
+This project maintains a set of benchmarks that measure Ajv, Value and TypeCompiler compilation and validation performance. These benchmarks can be run locally by cloning this repository and running `npm run benchmark`. The results below show for Ajv version 8.11.0. 
+
+For additional comparative benchmarks, please refer to [typescript-runtime-type-benchmarks](https://moltar.github.io/typescript-runtime-type-benchmarks/).
+
+<a name='benchmark-compile'></a>
+
+### Compile
+
+This benchmark measures compilation performance for varying types. You can review this benchmark [here](https://github.com/sinclairzx81/typebox/blob/master/benchmark/measurement/module/compile.ts).
+
+```typescript
+┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
+│     (index)      │ Iterations │     Ajv      │ TypeCompiler │ Performance  │
+├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
+│           Number │    2000    │ '    428 ms' │ '     12 ms' │ '   35.67 x' │
+│           String │    2000    │ '    337 ms' │ '     12 ms' │ '   28.08 x' │
+│          Boolean │    2000    │ '    317 ms' │ '     11 ms' │ '   28.82 x' │
+│             Null │    2000    │ '    274 ms' │ '     10 ms' │ '   27.40 x' │
+│            RegEx │    2000    │ '    500 ms' │ '     18 ms' │ '   27.78 x' │
+│          ObjectA │    2000    │ '   2717 ms' │ '     49 ms' │ '   55.45 x' │
+│          ObjectB │    2000    │ '   2854 ms' │ '     37 ms' │ '   77.14 x' │
+│            Tuple │    2000    │ '   1224 ms' │ '     21 ms' │ '   58.29 x' │
+│            Union │    2000    │ '   1266 ms' │ '     23 ms' │ '   55.04 x' │
+│          Vector4 │    2000    │ '   1513 ms' │ '     19 ms' │ '   79.63 x' │
+│          Matrix4 │    2000    │ '    841 ms' │ '     12 ms' │ '   70.08 x' │
+│   Literal_String │    2000    │ '    327 ms' │ '      8 ms' │ '   40.88 x' │
+│   Literal_Number │    2000    │ '    358 ms' │ '      6 ms' │ '   59.67 x' │
+│  Literal_Boolean │    2000    │ '    355 ms' │ '      5 ms' │ '   71.00 x' │
+│     Array_Number │    2000    │ '    685 ms' │ '      7 ms' │ '   97.86 x' │
+│     Array_String │    2000    │ '    716 ms' │ '     11 ms' │ '   65.09 x' │
+│    Array_Boolean │    2000    │ '    732 ms' │ '      6 ms' │ '  122.00 x' │
+│    Array_ObjectA │    2000    │ '   3503 ms' │ '     34 ms' │ '  103.03 x' │
+│    Array_ObjectB │    2000    │ '   3626 ms' │ '     38 ms' │ '   95.42 x' │
+│      Array_Tuple │    2000    │ '   2095 ms' │ '     21 ms' │ '   99.76 x' │
+│      Array_Union │    2000    │ '   1577 ms' │ '     22 ms' │ '   71.68 x' │
+│    Array_Vector4 │    2000    │ '   2172 ms' │ '     17 ms' │ '  127.76 x' │
+│    Array_Matrix4 │    2000    │ '   1468 ms' │ '     19 ms' │ '   77.26 x' │
+└──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
+```
+
+<a name='benchmark-validate'></a>
+
+### Validate
+
+This benchmark measures validation performance for varying types. You can review this benchmark [here](https://github.com/sinclairzx81/typebox/blob/master/benchmark/measurement/module/check.ts).
+
+```typescript
+┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
+│     (index)      │ Iterations │  ValueCheck  │     Ajv      │ TypeCompiler │ Performance  │
+├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
+│           Number │  1000000   │ '     24 ms' │ '      9 ms' │ '      6 ms' │ '    1.50 x' │
+│           String │  1000000   │ '     23 ms' │ '     19 ms' │ '     12 ms' │ '    1.58 x' │
+│          Boolean │  1000000   │ '     24 ms' │ '     19 ms' │ '     10 ms' │ '    1.90 x' │
+│             Null │  1000000   │ '     23 ms' │ '     18 ms' │ '      9 ms' │ '    2.00 x' │
+│            RegEx │  1000000   │ '    164 ms' │ '     46 ms' │ '     38 ms' │ '    1.21 x' │
+│          ObjectA │  1000000   │ '    548 ms' │ '     36 ms' │ '     22 ms' │ '    1.64 x' │
+│          ObjectB │  1000000   │ '   1118 ms' │ '     51 ms' │ '     38 ms' │ '    1.34 x' │
+│            Tuple │  1000000   │ '    136 ms' │ '     25 ms' │ '     14 ms' │ '    1.79 x' │
+│            Union │  1000000   │ '    338 ms' │ '     27 ms' │ '     16 ms' │ '    1.69 x' │
+│        Recursive │  1000000   │ '   3251 ms' │ '    416 ms' │ '     98 ms' │ '    4.24 x' │
+│          Vector4 │  1000000   │ '    146 ms' │ '     23 ms' │ '     12 ms' │ '    1.92 x' │
+│          Matrix4 │  1000000   │ '    584 ms' │ '     40 ms' │ '     25 ms' │ '    1.60 x' │
+│   Literal_String │  1000000   │ '     46 ms' │ '     19 ms' │ '     10 ms' │ '    1.90 x' │
+│   Literal_Number │  1000000   │ '     46 ms' │ '     20 ms' │ '     10 ms' │ '    2.00 x' │
+│  Literal_Boolean │  1000000   │ '     47 ms' │ '     21 ms' │ '     10 ms' │ '    2.10 x' │
+│     Array_Number │  1000000   │ '    456 ms' │ '     31 ms' │ '     19 ms' │ '    1.63 x' │
+│     Array_String │  1000000   │ '    489 ms' │ '     40 ms' │ '     25 ms' │ '    1.60 x' │
+│    Array_Boolean │  1000000   │ '    458 ms' │ '     35 ms' │ '     27 ms' │ '    1.30 x' │
+│    Array_ObjectA │  1000000   │ '  13559 ms' │ '   2568 ms' │ '   1564 ms' │ '    1.64 x' │
+│    Array_ObjectB │  1000000   │ '  15863 ms' │ '   2744 ms' │ '   2060 ms' │ '    1.33 x' │
+│      Array_Tuple │  1000000   │ '   1694 ms' │ '     96 ms' │ '     63 ms' │ '    1.52 x' │
+│      Array_Union │  1000000   │ '   4736 ms' │ '    229 ms' │ '     86 ms' │ '    2.66 x' │
+│  Array_Recursive │  1000000   │ '  53804 ms' │ '   6744 ms' │ '   1167 ms' │ '    5.78 x' │
+│    Array_Vector4 │  1000000   │ '   2244 ms' │ '     99 ms' │ '     46 ms' │ '    2.15 x' │
+│    Array_Matrix4 │  1000000   │ '  11966 ms' │ '    378 ms' │ '    229 ms' │ '    1.65 x' │
+└──────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
+```
+
+<a name='benchmark-compression'></a>
+
+### Compression
+
+The following table lists esbuild compiled and minified sizes for each TypeBox module.
+
+```typescript
+┌──────────────────────┬────────────┬────────────┬─────────────┐
+│       (index)        │  Compiled  │  Minified  │ Compression │
+├──────────────────────┼────────────┼────────────┼─────────────┤
+│ typebox/compiler     │ '   51 kb' │ '   25 kb' │  '2.00 x'   │
+│ typebox/conditional  │ '   42 kb' │ '   17 kb' │  '2.46 x'   │
+│ typebox/format       │ '    0 kb' │ '    0 kb' │  '2.66 x'   │
+│ typebox/guard        │ '   21 kb' │ '   10 kb' │  '2.08 x'   │
+│ typebox/value        │ '   74 kb' │ '   34 kb' │  '2.16 x'   │
+│ typebox              │ '   11 kb' │ '    6 kb' │  '1.91 x'   │
+└──────────────────────┴────────────┴────────────┴─────────────┘
+```
+
+<a name='contribute'></a>
+
+## Contribute
+
+TypeBox is open to community contribution. Please ensure you submit an open issue before submitting your pull request. The TypeBox project preferences open community discussion prior to accepting new features.
Index: frontend/node_modules/@sinclair/typebox/typebox.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/typebox.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/typebox.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,408 @@
+export declare const Kind: unique symbol;
+export declare const Hint: unique symbol;
+export declare const Modifier: unique symbol;
+export declare type TModifier = TReadonlyOptional<TSchema> | TOptional<TSchema> | TReadonly<TSchema>;
+export declare type TReadonly<T extends TSchema> = T & {
+    [Modifier]: 'Readonly';
+};
+export declare type TOptional<T extends TSchema> = T & {
+    [Modifier]: 'Optional';
+};
+export declare type TReadonlyOptional<T extends TSchema> = T & {
+    [Modifier]: 'ReadonlyOptional';
+};
+export interface SchemaOptions {
+    $schema?: string;
+    /** Id for this schema */
+    $id?: string;
+    /** Title of this schema */
+    title?: string;
+    /** Description of this schema */
+    description?: string;
+    /** Default value for this schema */
+    default?: any;
+    /** Example values matching this schema. */
+    examples?: any;
+    [prop: string]: any;
+}
+export interface TSchema extends SchemaOptions {
+    [Kind]: string;
+    [Hint]?: string;
+    [Modifier]?: string;
+    params: unknown[];
+    static: unknown;
+}
+export declare type TAnySchema = TSchema | TAny | TArray | TBoolean | TConstructor | TEnum | TFunction | TInteger | TLiteral | TNull | TNumber | TObject | TPromise | TRecord | TSelf | TRef | TString | TTuple | TUndefined | TUnion | TUint8Array | TUnknown | TVoid;
+export interface NumericOptions extends SchemaOptions {
+    exclusiveMaximum?: number;
+    exclusiveMinimum?: number;
+    maximum?: number;
+    minimum?: number;
+    multipleOf?: number;
+}
+export declare type TNumeric = TInteger | TNumber;
+export interface TAny extends TSchema {
+    [Kind]: 'Any';
+    static: any;
+}
+export interface ArrayOptions extends SchemaOptions {
+    uniqueItems?: boolean;
+    minItems?: number;
+    maxItems?: number;
+}
+export interface TArray<T extends TSchema = TSchema> extends TSchema, ArrayOptions {
+    [Kind]: 'Array';
+    static: Array<Static<T, this['params']>>;
+    type: 'array';
+    items: T;
+}
+export interface TBoolean extends TSchema {
+    [Kind]: 'Boolean';
+    static: boolean;
+    type: 'boolean';
+}
+export declare type TConstructorParameters<T extends TConstructor<TSchema[], TSchema>> = TTuple<T['parameters']>;
+export declare type TInstanceType<T extends TConstructor<TSchema[], TSchema>> = T['returns'];
+export declare type StaticContructorParameters<T extends readonly TSchema[], P extends unknown[]> = [...{
+    [K in keyof T]: T[K] extends TSchema ? Static<T[K], P> : never;
+}];
+export interface TConstructor<T extends TSchema[] = TSchema[], U extends TSchema = TSchema> extends TSchema {
+    [Kind]: 'Constructor';
+    static: new (...param: StaticContructorParameters<T, this['params']>) => Static<U, this['params']>;
+    type: 'constructor';
+    parameters: T;
+    returns: U;
+}
+export interface TEnumOption<T> {
+    type: 'number' | 'string';
+    const: T;
+}
+export interface TEnum<T extends Record<string, string | number> = Record<string, string | number>> extends TSchema {
+    [Kind]: 'Union';
+    static: T[keyof T];
+    anyOf: TLiteral<string | number>[];
+}
+export declare type TParameters<T extends TFunction> = TTuple<T['parameters']>;
+export declare type TReturnType<T extends TFunction> = T['returns'];
+export declare type StaticFunctionParameters<T extends readonly TSchema[], P extends unknown[]> = [...{
+    [K in keyof T]: T[K] extends TSchema ? Static<T[K], P> : never;
+}];
+export interface TFunction<T extends readonly TSchema[] = TSchema[], U extends TSchema = TSchema> extends TSchema {
+    [Kind]: 'Function';
+    static: (...param: StaticFunctionParameters<T, this['params']>) => Static<U, this['params']>;
+    type: 'function';
+    parameters: T;
+    returns: U;
+}
+export interface TInteger extends TSchema, NumericOptions {
+    [Kind]: 'Integer';
+    static: number;
+    type: 'integer';
+}
+export declare type IntersectReduce<I extends unknown, T extends readonly any[]> = T extends [infer A, ...infer B] ? IntersectReduce<I & A, B> : I extends object ? I : {};
+export declare type IntersectEvaluate<T extends readonly TSchema[], P extends unknown[]> = {
+    [K in keyof T]: T[K] extends TSchema ? Static<T[K], P> : never;
+};
+export declare type IntersectProperties<T extends readonly TObject[]> = {
+    [K in keyof T]: T[K] extends TObject<infer P> ? P : {};
+};
+export interface TIntersect<T extends TObject[] = TObject[]> extends TObject {
+    static: IntersectReduce<unknown, IntersectEvaluate<T, this['params']>>;
+    properties: IntersectReduce<unknown, IntersectProperties<T>>;
+}
+export declare type UnionToIntersect<U> = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never;
+export declare type UnionLast<U> = UnionToIntersect<U extends unknown ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L : never;
+export declare type UnionToTuple<U, L = UnionLast<U>> = [U] extends [never] ? [] : [...UnionToTuple<Exclude<U, L>>, L];
+export declare type UnionStringLiteralToTuple<T> = T extends TUnion<infer L> ? {
+    [I in keyof L]: L[I] extends TLiteral<infer C> ? C : never;
+} : never;
+export declare type UnionLiteralsFromObject<T extends TObject> = {
+    [K in ObjectPropertyKeys<T>]: TLiteral<K>;
+} extends infer R ? UnionToTuple<R[keyof R]> : never;
+export interface TKeyOf<T extends TObject> extends TUnion<UnionLiteralsFromObject<T>> {
+}
+export declare type TLiteralValue = string | number | boolean;
+export interface TLiteral<T extends TLiteralValue = TLiteralValue> extends TSchema {
+    [Kind]: 'Literal';
+    static: T;
+    const: T;
+}
+export interface TNever extends TSchema {
+    [Kind]: 'Never';
+    static: never;
+    allOf: [{
+        type: 'boolean';
+        const: false;
+    }, {
+        type: 'boolean';
+        const: true;
+    }];
+}
+export interface TNull extends TSchema {
+    [Kind]: 'Null';
+    static: null;
+    type: 'null';
+}
+export interface TNumber extends TSchema, NumericOptions {
+    [Kind]: 'Number';
+    static: number;
+    type: 'number';
+}
+export declare type ReadonlyOptionalPropertyKeys<T extends TProperties> = {
+    [K in keyof T]: T[K] extends TReadonlyOptional<TSchema> ? K : never;
+}[keyof T];
+export declare type ReadonlyPropertyKeys<T extends TProperties> = {
+    [K in keyof T]: T[K] extends TReadonly<TSchema> ? K : never;
+}[keyof T];
+export declare type OptionalPropertyKeys<T extends TProperties> = {
+    [K in keyof T]: T[K] extends TOptional<TSchema> ? K : never;
+}[keyof T];
+export declare type RequiredPropertyKeys<T extends TProperties> = keyof Omit<T, ReadonlyOptionalPropertyKeys<T> | ReadonlyPropertyKeys<T> | OptionalPropertyKeys<T>>;
+export declare type PropertiesReduce<T extends TProperties, P extends unknown[]> = {
+    readonly [K in ReadonlyOptionalPropertyKeys<T>]?: Static<T[K], P>;
+} & {
+    readonly [K in ReadonlyPropertyKeys<T>]: Static<T[K], P>;
+} & {
+    [K in OptionalPropertyKeys<T>]?: Static<T[K], P>;
+} & {
+    [K in RequiredPropertyKeys<T>]: Static<T[K], P>;
+} extends infer R ? {
+    [K in keyof R]: R[K];
+} : never;
+export declare type TRecordProperties<K extends TUnion<TLiteral[]>, T extends TSchema> = Static<K> extends string ? {
+    [X in Static<K>]: T;
+} : never;
+export interface TProperties {
+    [key: string]: TSchema;
+}
+export declare type ObjectProperties<T> = T extends TObject<infer U> ? U : never;
+export declare type ObjectPropertyKeys<T> = T extends TObject<infer U> ? keyof U : never;
+export declare type TAdditionalProperties = undefined | TSchema | boolean;
+export interface ObjectOptions extends SchemaOptions {
+    additionalProperties?: TAdditionalProperties;
+    minProperties?: number;
+    maxProperties?: number;
+}
+export interface TObject<T extends TProperties = TProperties> extends TSchema, ObjectOptions {
+    [Kind]: 'Object';
+    static: PropertiesReduce<T, this['params']>;
+    additionalProperties?: TAdditionalProperties;
+    type: 'object';
+    properties: T;
+    required?: string[];
+}
+export interface TOmit<T extends TObject, Properties extends ObjectPropertyKeys<T>[]> extends TObject, ObjectOptions {
+    static: Omit<Static<T, this['params']>, Properties[number]>;
+    properties: T extends TObject ? Omit<T['properties'], Properties[number]> : never;
+}
+export interface TPartial<T extends TObject> extends TObject {
+    static: Partial<Static<T, this['params']>>;
+    properties: {
+        [K in keyof T['properties']]: T['properties'][K] extends TReadonlyOptional<infer U> ? TReadonlyOptional<U> : T['properties'][K] extends TReadonly<infer U> ? TReadonlyOptional<U> : T['properties'][K] extends TOptional<infer U> ? TOptional<U> : TOptional<T['properties'][K]>;
+    };
+}
+export declare type TPick<T extends TObject, Properties extends ObjectPropertyKeys<T>[]> = TObject<{
+    [K in Properties[number]]: T['properties'][K];
+}>;
+export interface TPromise<T extends TSchema = TSchema> extends TSchema {
+    [Kind]: 'Promise';
+    static: Promise<Static<T, this['params']>>;
+    type: 'promise';
+    item: TSchema;
+}
+export declare type TRecordKey = TString | TNumeric | TUnion<TLiteral<any>[]>;
+export interface TRecord<K extends TRecordKey = TRecordKey, T extends TSchema = TSchema> extends TSchema {
+    [Kind]: 'Record';
+    static: Record<Static<K>, Static<T, this['params']>>;
+    type: 'object';
+    patternProperties: {
+        [pattern: string]: T;
+    };
+    additionalProperties: false;
+}
+export interface TSelf extends TSchema {
+    [Kind]: 'Self';
+    static: this['params'][0];
+    $ref: string;
+}
+export declare type TRecursiveReduce<T extends TSchema> = Static<T, [TRecursiveReduce<T>]>;
+export interface TRecursive<T extends TSchema> extends TSchema {
+    static: TRecursiveReduce<T>;
+}
+export interface TRef<T extends TSchema = TSchema> extends TSchema {
+    [Kind]: 'Ref';
+    static: Static<T, this['params']>;
+    $ref: string;
+}
+export interface TRequired<T extends TObject | TRef<TObject>> extends TObject {
+    static: Required<Static<T, this['params']>>;
+    properties: {
+        [K in keyof T['properties']]: T['properties'][K] extends TReadonlyOptional<infer U> ? TReadonly<U> : T['properties'][K] extends TReadonly<infer U> ? TReadonly<U> : T['properties'][K] extends TOptional<infer U> ? U : T['properties'][K];
+    };
+}
+export declare type StringFormatOption = 'date-time' | 'time' | 'date' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri' | 'uri-reference' | 'iri' | 'uuid' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'relative-json-pointer' | 'regex';
+export interface StringOptions<Format extends string> extends SchemaOptions {
+    minLength?: number;
+    maxLength?: number;
+    pattern?: string;
+    format?: Format;
+    contentEncoding?: '7bit' | '8bit' | 'binary' | 'quoted-printable' | 'base64';
+    contentMediaType?: string;
+}
+export interface TString<Format extends string = string> extends TSchema, StringOptions<Format> {
+    [Kind]: 'String';
+    static: string;
+    type: 'string';
+}
+export declare type TupleToArray<T extends TTuple<TSchema[]>> = T extends TTuple<infer R> ? R : never;
+export interface TTuple<T extends TSchema[] = TSchema[]> extends TSchema {
+    [Kind]: 'Tuple';
+    static: {
+        [K in keyof T]: T[K] extends TSchema ? Static<T[K], this['params']> : T[K];
+    };
+    type: 'array';
+    items?: T;
+    additionalItems?: false;
+    minItems: number;
+    maxItems: number;
+}
+export interface TUndefined extends TSchema {
+    [Kind]: 'Undefined';
+    specialized: 'Undefined';
+    static: undefined;
+    type: 'object';
+}
+export interface TUnion<T extends TSchema[] = TSchema[]> extends TSchema {
+    [Kind]: 'Union';
+    static: {
+        [K in keyof T]: T[K] extends TSchema ? Static<T[K], this['params']> : never;
+    }[number];
+    anyOf: T;
+}
+export interface Uint8ArrayOptions extends SchemaOptions {
+    maxByteLength?: number;
+    minByteLength?: number;
+}
+export interface TUint8Array extends TSchema, Uint8ArrayOptions {
+    [Kind]: 'Uint8Array';
+    static: Uint8Array;
+    specialized: 'Uint8Array';
+    type: 'object';
+}
+export interface TUnknown extends TSchema {
+    [Kind]: 'Unknown';
+    static: unknown;
+}
+export interface UnsafeOptions extends SchemaOptions {
+    [Kind]?: string;
+}
+export interface TUnsafe<T> extends TSchema {
+    [Kind]: string;
+    static: T;
+}
+export interface TVoid extends TSchema {
+    [Kind]: 'Void';
+    static: void;
+    type: 'null';
+}
+/** Creates a static type from a TypeBox type */
+export declare type Static<T extends TSchema, P extends unknown[] = []> = (T & {
+    params: P;
+})['static'];
+export declare class TypeBuilder {
+    /** Creates a readonly optional property */
+    ReadonlyOptional<T extends TSchema>(item: T): TReadonlyOptional<T>;
+    /** Creates a readonly property */
+    Readonly<T extends TSchema>(item: T): TReadonly<T>;
+    /** Creates a optional property */
+    Optional<T extends TSchema>(item: T): TOptional<T>;
+    /** Creates a any type */
+    Any(options?: SchemaOptions): TAny;
+    /** Creates a array type */
+    Array<T extends TSchema>(items: T, options?: ArrayOptions): TArray<T>;
+    /** Creates a boolean type */
+    Boolean(options?: SchemaOptions): TBoolean;
+    /** Creates a tuple type from this constructors parameters */
+    ConstructorParameters<T extends TConstructor<any[], any>>(schema: T, options?: SchemaOptions): TConstructorParameters<T>;
+    /** Creates a constructor type */
+    Constructor<T extends TTuple<TSchema[]>, U extends TSchema>(parameters: T, returns: U, options?: SchemaOptions): TConstructor<TupleToArray<T>, U>;
+    /** Creates a constructor type */
+    Constructor<T extends TSchema[], U extends TSchema>(parameters: [...T], returns: U, options?: SchemaOptions): TConstructor<T, U>;
+    /** Creates a enum type */
+    Enum<T extends Record<string, string | number>>(item: T, options?: SchemaOptions): TEnum<T>;
+    /** Creates a function type */
+    Function<T extends TTuple<TSchema[]>, U extends TSchema>(parameters: T, returns: U, options?: SchemaOptions): TFunction<TupleToArray<T>, U>;
+    /** Creates a function type */
+    Function<T extends TSchema[], U extends TSchema>(parameters: [...T], returns: U, options?: SchemaOptions): TFunction<T, U>;
+    /** Creates a type from this constructors instance type */
+    InstanceType<T extends TConstructor<any[], any>>(schema: T, options?: SchemaOptions): TInstanceType<T>;
+    /** Creates a integer type */
+    Integer(options?: NumericOptions): TInteger;
+    /** Creates a intersect type. */
+    Intersect<T extends TObject[]>(objects: [...T], options?: ObjectOptions): TIntersect<T>;
+    /** Creates a keyof type */
+    KeyOf<T extends TObject>(object: T, options?: SchemaOptions): TKeyOf<T>;
+    /** Creates a literal type. */
+    Literal<T extends TLiteralValue>(value: T, options?: SchemaOptions): TLiteral<T>;
+    /** Creates a never type */
+    Never(options?: SchemaOptions): TNever;
+    /** Creates a null type */
+    Null(options?: SchemaOptions): TNull;
+    /** Creates a number type */
+    Number(options?: NumericOptions): TNumber;
+    /** Creates an object type with the given properties */
+    Object<T extends TProperties>(properties: T, options?: ObjectOptions): TObject<T>;
+    /** Creates a new object whose properties are omitted from the given object */
+    Omit<T extends TObject, K extends TUnion<TLiteral<string>[]>>(schema: T, keys: K, options?: ObjectOptions): TOmit<T, UnionStringLiteralToTuple<K>>;
+    /** Creates a new object whose properties are omitted from the given object */
+    Omit<T extends TObject, K extends ObjectPropertyKeys<T>[]>(schema: T, keys: readonly [...K], options?: ObjectOptions): TOmit<T, K>;
+    /** Creates a tuple type from this functions parameters */
+    Parameters<T extends TFunction<any[], any>>(schema: T, options?: SchemaOptions): TParameters<T>;
+    /** Creates an object type whose properties are all optional */
+    Partial<T extends TObject>(schema: T, options?: ObjectOptions): TPartial<T>;
+    /** Creates a object whose properties are picked from the given object */
+    Pick<T extends TObject, K extends TUnion<TLiteral<string>[]>>(schema: T, keys: K, options?: ObjectOptions): TPick<T, UnionStringLiteralToTuple<K>>;
+    /** Creates a object whose properties are picked from the given object */
+    Pick<T extends TObject, K extends ObjectPropertyKeys<T>[]>(schema: T, keys: readonly [...K], options?: ObjectOptions): TPick<T, K>;
+    /** Creates a promise type. This type cannot be represented in schema. */
+    Promise<T extends TSchema>(item: T, options?: SchemaOptions): TPromise<T>;
+    /** Creates an object whose properties are derived from the given string literal union. */
+    Record<K extends TUnion<TLiteral[]>, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): TObject<TRecordProperties<K, T>>;
+    /** Creates a record type */
+    Record<K extends TString | TNumeric, T extends TSchema>(key: K, schema: T, options?: ObjectOptions): TRecord<K, T>;
+    /** Creates a recursive object type */
+    Recursive<T extends TSchema>(callback: (self: TSelf) => T, options?: SchemaOptions): TRecursive<T>;
+    /** Creates a reference schema */
+    Ref<T extends TSchema>(schema: T, options?: SchemaOptions): TRef<T>;
+    /** Creates a string type from a regular expression */
+    RegEx(regex: RegExp, options?: SchemaOptions): TString;
+    /** Creates an object type whose properties are all required */
+    Required<T extends TObject>(schema: T, options?: SchemaOptions): TRequired<T>;
+    /** Creates a type from this functions return type */
+    ReturnType<T extends TFunction<any[], any>>(schema: T, options?: SchemaOptions): TReturnType<T>;
+    /** Removes Kind and Modifier symbol property keys from this schema */
+    Strict<T extends TSchema>(schema: T): T;
+    /** Creates a string type */
+    String<Format extends string>(options?: StringOptions<StringFormatOption | Format>): TString<Format>;
+    /** Creates a tuple type */
+    Tuple<T extends TSchema[]>(items: [...T], options?: SchemaOptions): TTuple<T>;
+    /** Creates a undefined type */
+    Undefined(options?: SchemaOptions): TUndefined;
+    /** Creates a union type */
+    Union(items: [], options?: SchemaOptions): TNever;
+    Union<T extends TSchema[]>(items: [...T], options?: SchemaOptions): TUnion<T>;
+    /** Creates a Uint8Array type */
+    Uint8Array(options?: Uint8ArrayOptions): TUint8Array;
+    /** Creates an unknown type */
+    Unknown(options?: SchemaOptions): TUnknown;
+    /** Creates a user defined schema that infers as type T  */
+    Unsafe<T>(options?: UnsafeOptions): TUnsafe<T>;
+    /** Creates a void type */
+    Void(options?: SchemaOptions): TVoid;
+    /** Use this function to return TSchema with static and params omitted */
+    protected Create<T>(schema: Omit<T, 'static' | 'params'>): T;
+    /** Clones the given value */
+    protected Clone(value: any): any;
+}
+/** JSON Schema Type Builder with Static Type Resolution for TypeScript */
+export declare const Type: TypeBuilder;
Index: frontend/node_modules/@sinclair/typebox/typebox.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/typebox.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/typebox.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,383 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Type = exports.TypeBuilder = exports.Modifier = exports.Hint = exports.Kind = void 0;
+// --------------------------------------------------------------------------
+// Symbols
+// --------------------------------------------------------------------------
+exports.Kind = Symbol.for('TypeBox.Kind');
+exports.Hint = Symbol.for('TypeBox.Hint');
+exports.Modifier = Symbol.for('TypeBox.Modifier');
+// --------------------------------------------------------------------------
+// TypeBuilder
+// --------------------------------------------------------------------------
+let TypeOrdinal = 0;
+class TypeBuilder {
+    // ----------------------------------------------------------------------
+    // Modifiers
+    // ----------------------------------------------------------------------
+    /** Creates a readonly optional property */
+    ReadonlyOptional(item) {
+        return { [exports.Modifier]: 'ReadonlyOptional', ...item };
+    }
+    /** Creates a readonly property */
+    Readonly(item) {
+        return { [exports.Modifier]: 'Readonly', ...item };
+    }
+    /** Creates a optional property */
+    Optional(item) {
+        return { [exports.Modifier]: 'Optional', ...item };
+    }
+    // ----------------------------------------------------------------------
+    // Types
+    // ----------------------------------------------------------------------
+    /** Creates a any type */
+    Any(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Any' });
+    }
+    /** Creates a array type */
+    Array(items, options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Array', type: 'array', items });
+    }
+    /** Creates a boolean type */
+    Boolean(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Boolean', type: 'boolean' });
+    }
+    /** Creates a tuple type from this constructors parameters */
+    ConstructorParameters(schema, options = {}) {
+        return this.Tuple([...schema.parameters], { ...options });
+    }
+    /** Creates a constructor type */
+    Constructor(parameters, returns, options = {}) {
+        if (parameters[exports.Kind] === 'Tuple') {
+            const inner = parameters.items === undefined ? [] : parameters.items;
+            return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'constructor', parameters: inner, returns });
+        }
+        else if (globalThis.Array.isArray(parameters)) {
+            return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'constructor', parameters, returns });
+        }
+        else {
+            throw new Error('TypeBuilder.Constructor: Invalid parameters');
+        }
+    }
+    /** Creates a enum type */
+    Enum(item, options = {}) {
+        const values = Object.keys(item)
+            .filter((key) => isNaN(key))
+            .map((key) => item[key]);
+        const anyOf = values.map((value) => (typeof value === 'string' ? { [exports.Kind]: 'Literal', type: 'string', const: value } : { [exports.Kind]: 'Literal', type: 'number', const: value }));
+        return this.Create({ ...options, [exports.Kind]: 'Union', [exports.Hint]: 'Enum', anyOf });
+    }
+    /** Creates a function type */
+    Function(parameters, returns, options = {}) {
+        if (parameters[exports.Kind] === 'Tuple') {
+            const inner = parameters.items === undefined ? [] : parameters.items;
+            return this.Create({ ...options, [exports.Kind]: 'Function', type: 'function', parameters: inner, returns });
+        }
+        else if (globalThis.Array.isArray(parameters)) {
+            return this.Create({ ...options, [exports.Kind]: 'Function', type: 'function', parameters, returns });
+        }
+        else {
+            throw new Error('TypeBuilder.Function: Invalid parameters');
+        }
+    }
+    /** Creates a type from this constructors instance type */
+    InstanceType(schema, options = {}) {
+        return { ...options, ...this.Clone(schema.returns) };
+    }
+    /** Creates a integer type */
+    Integer(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Integer', type: 'integer' });
+    }
+    /** Creates a intersect type. */
+    Intersect(objects, options = {}) {
+        const isOptional = (schema) => (schema[exports.Modifier] && schema[exports.Modifier] === 'Optional') || schema[exports.Modifier] === 'ReadonlyOptional';
+        const [required, optional] = [new Set(), new Set()];
+        for (const object of objects) {
+            for (const [key, schema] of Object.entries(object.properties)) {
+                if (isOptional(schema))
+                    optional.add(key);
+            }
+        }
+        for (const object of objects) {
+            for (const key of Object.keys(object.properties)) {
+                if (!optional.has(key))
+                    required.add(key);
+            }
+        }
+        const properties = {};
+        for (const object of objects) {
+            for (const [key, schema] of Object.entries(object.properties)) {
+                properties[key] = properties[key] === undefined ? schema : { [exports.Kind]: 'Union', anyOf: [properties[key], { ...schema }] };
+            }
+        }
+        if (required.size > 0) {
+            return this.Create({ ...options, [exports.Kind]: 'Object', type: 'object', properties, required: [...required] });
+        }
+        else {
+            return this.Create({ ...options, [exports.Kind]: 'Object', type: 'object', properties });
+        }
+    }
+    /** Creates a keyof type */
+    KeyOf(object, options = {}) {
+        const items = Object.keys(object.properties).map((key) => this.Create({ ...options, [exports.Kind]: 'Literal', type: 'string', const: key }));
+        return this.Create({ ...options, [exports.Kind]: 'Union', [exports.Hint]: 'KeyOf', anyOf: items });
+    }
+    /** Creates a literal type. */
+    Literal(value, options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Literal', const: value, type: typeof value });
+    }
+    /** Creates a never type */
+    Never(options = {}) {
+        return this.Create({
+            ...options,
+            [exports.Kind]: 'Never',
+            allOf: [
+                { type: 'boolean', const: false },
+                { type: 'boolean', const: true },
+            ],
+        });
+    }
+    /** Creates a null type */
+    Null(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Null', type: 'null' });
+    }
+    /** Creates a number type */
+    Number(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Number', type: 'number' });
+    }
+    /** Creates an object type with the given properties */
+    Object(properties, options = {}) {
+        const property_names = Object.keys(properties);
+        const optional = property_names.filter((name) => {
+            const property = properties[name];
+            const modifier = property[exports.Modifier];
+            return modifier && (modifier === 'Optional' || modifier === 'ReadonlyOptional');
+        });
+        const required = property_names.filter((name) => !optional.includes(name));
+        if (required.length > 0) {
+            return this.Create({ ...options, [exports.Kind]: 'Object', type: 'object', properties, required });
+        }
+        else {
+            return this.Create({ ...options, [exports.Kind]: 'Object', type: 'object', properties });
+        }
+    }
+    /** Creates a new object whose properties are omitted from the given object */
+    Omit(schema, keys, options = {}) {
+        const select = keys[exports.Kind] === 'Union' ? keys.anyOf.map((schema) => schema.const) : keys;
+        const next = { ...this.Clone(schema), ...options, [exports.Hint]: 'Omit' };
+        if (next.required) {
+            next.required = next.required.filter((key) => !select.includes(key));
+            if (next.required.length === 0)
+                delete next.required;
+        }
+        for (const key of Object.keys(next.properties)) {
+            if (select.includes(key))
+                delete next.properties[key];
+        }
+        return this.Create(next);
+    }
+    /** Creates a tuple type from this functions parameters */
+    Parameters(schema, options = {}) {
+        return exports.Type.Tuple(schema.parameters, { ...options });
+    }
+    /** Creates an object type whose properties are all optional */
+    Partial(schema, options = {}) {
+        const next = { ...this.Clone(schema), ...options, [exports.Hint]: 'Partial' };
+        delete next.required;
+        for (const key of Object.keys(next.properties)) {
+            const property = next.properties[key];
+            const modifer = property[exports.Modifier];
+            switch (modifer) {
+                case 'ReadonlyOptional':
+                    property[exports.Modifier] = 'ReadonlyOptional';
+                    break;
+                case 'Readonly':
+                    property[exports.Modifier] = 'ReadonlyOptional';
+                    break;
+                case 'Optional':
+                    property[exports.Modifier] = 'Optional';
+                    break;
+                default:
+                    property[exports.Modifier] = 'Optional';
+                    break;
+            }
+        }
+        return this.Create(next);
+    }
+    /** Creates a object whose properties are picked from the given object */
+    Pick(schema, keys, options = {}) {
+        const select = keys[exports.Kind] === 'Union' ? keys.anyOf.map((schema) => schema.const) : keys;
+        const next = { ...this.Clone(schema), ...options, [exports.Hint]: 'Pick' };
+        if (next.required) {
+            next.required = next.required.filter((key) => select.includes(key));
+            if (next.required.length === 0)
+                delete next.required;
+        }
+        for (const key of Object.keys(next.properties)) {
+            if (!select.includes(key))
+                delete next.properties[key];
+        }
+        return this.Create(next);
+    }
+    /** Creates a promise type. This type cannot be represented in schema. */
+    Promise(item, options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Promise', type: 'promise', item });
+    }
+    /** Creates a record type */
+    Record(key, value, options = {}) {
+        // If string literal union return TObject with properties extracted from union.
+        if (key[exports.Kind] === 'Union') {
+            return this.Object(key.anyOf.reduce((acc, literal) => {
+                return { ...acc, [literal.const]: value };
+            }, {}), { ...options, [exports.Hint]: 'Record' });
+        }
+        // otherwise return TRecord with patternProperties
+        const pattern = ['Integer', 'Number'].includes(key[exports.Kind]) ? '^(0|[1-9][0-9]*)$' : key[exports.Kind] === 'String' && key.pattern ? key.pattern : '^.*$';
+        return this.Create({
+            ...options,
+            [exports.Kind]: 'Record',
+            type: 'object',
+            patternProperties: { [pattern]: value },
+            additionalProperties: false,
+        });
+    }
+    /** Creates a recursive object type */
+    Recursive(callback, options = {}) {
+        if (options.$id === undefined)
+            options.$id = `T${TypeOrdinal++}`;
+        const self = callback({ [exports.Kind]: 'Self', $ref: `${options.$id}` });
+        self.$id = options.$id;
+        return this.Create({ ...options, ...self });
+    }
+    /** Creates a reference schema */
+    Ref(schema, options = {}) {
+        if (schema.$id === undefined)
+            throw Error('TypeBuilder.Ref: Referenced schema must specify an $id');
+        return this.Create({ ...options, [exports.Kind]: 'Ref', $ref: schema.$id });
+    }
+    /** Creates a string type from a regular expression */
+    RegEx(regex, options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'String', type: 'string', pattern: regex.source });
+    }
+    /** Creates an object type whose properties are all required */
+    Required(schema, options = {}) {
+        const next = { ...this.Clone(schema), ...options, [exports.Hint]: 'Required' };
+        next.required = Object.keys(next.properties);
+        for (const key of Object.keys(next.properties)) {
+            const property = next.properties[key];
+            const modifier = property[exports.Modifier];
+            switch (modifier) {
+                case 'ReadonlyOptional':
+                    property[exports.Modifier] = 'Readonly';
+                    break;
+                case 'Readonly':
+                    property[exports.Modifier] = 'Readonly';
+                    break;
+                case 'Optional':
+                    delete property[exports.Modifier];
+                    break;
+                default:
+                    delete property[exports.Modifier];
+                    break;
+            }
+        }
+        return this.Create(next);
+    }
+    /** Creates a type from this functions return type */
+    ReturnType(schema, options = {}) {
+        return { ...options, ...this.Clone(schema.returns) };
+    }
+    /** Removes Kind and Modifier symbol property keys from this schema */
+    Strict(schema) {
+        return JSON.parse(JSON.stringify(schema));
+    }
+    /** Creates a string type */
+    String(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'String', type: 'string' });
+    }
+    /** Creates a tuple type */
+    Tuple(items, options = {}) {
+        const additionalItems = false;
+        const minItems = items.length;
+        const maxItems = items.length;
+        const schema = (items.length > 0 ? { ...options, [exports.Kind]: 'Tuple', type: 'array', items, additionalItems, minItems, maxItems } : { ...options, [exports.Kind]: 'Tuple', type: 'array', minItems, maxItems });
+        return this.Create(schema);
+    }
+    /** Creates a undefined type */
+    Undefined(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Undefined', type: 'object', specialized: 'Undefined' });
+    }
+    Union(items, options = {}) {
+        return items.length === 0 ? exports.Type.Never({ ...options }) : this.Create({ ...options, [exports.Kind]: 'Union', anyOf: items });
+    }
+    /** Creates a Uint8Array type */
+    Uint8Array(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Uint8Array', type: 'object', specialized: 'Uint8Array' });
+    }
+    /** Creates an unknown type */
+    Unknown(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Unknown' });
+    }
+    /** Creates a user defined schema that infers as type T  */
+    Unsafe(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: options[exports.Kind] || 'Unsafe' });
+    }
+    /** Creates a void type */
+    Void(options = {}) {
+        return this.Create({ ...options, [exports.Kind]: 'Void', type: 'null' });
+    }
+    /** Use this function to return TSchema with static and params omitted */
+    Create(schema) {
+        return schema;
+    }
+    /** Clones the given value */
+    Clone(value) {
+        const isObject = (object) => typeof object === 'object' && object !== null && !Array.isArray(object);
+        const isArray = (object) => typeof object === 'object' && object !== null && Array.isArray(object);
+        if (isObject(value)) {
+            return Object.keys(value).reduce((acc, key) => ({
+                ...acc,
+                [key]: this.Clone(value[key]),
+            }), Object.getOwnPropertySymbols(value).reduce((acc, key) => ({
+                ...acc,
+                [key]: this.Clone(value[key]),
+            }), {}));
+        }
+        else if (isArray(value)) {
+            return value.map((item) => this.Clone(item));
+        }
+        else {
+            return value;
+        }
+    }
+}
+exports.TypeBuilder = TypeBuilder;
+/** JSON Schema Type Builder with Static Type Resolution for TypeScript */
+exports.Type = new TypeBuilder();
Index: frontend/node_modules/@sinclair/typebox/value/cast.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/cast.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/cast.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,26 @@
+import * as Types from '../typebox';
+export declare class ValueCastReferenceTypeError extends Error {
+    readonly schema: Types.TRef | Types.TSelf;
+    constructor(schema: Types.TRef | Types.TSelf);
+}
+export declare class ValueCastArrayUniqueItemsTypeError extends Error {
+    readonly schema: Types.TSchema;
+    readonly value: unknown;
+    constructor(schema: Types.TSchema, value: unknown);
+}
+export declare class ValueCastNeverTypeError extends Error {
+    readonly schema: Types.TSchema;
+    constructor(schema: Types.TSchema);
+}
+export declare class ValueCastRecursiveTypeError extends Error {
+    readonly schema: Types.TSchema;
+    constructor(schema: Types.TSchema);
+}
+export declare class ValueCastUnknownTypeError extends Error {
+    readonly schema: Types.TSchema;
+    constructor(schema: Types.TSchema);
+}
+export declare namespace ValueCast {
+    function Visit(schema: Types.TSchema, references: Types.TSchema[], value: any): any;
+    function Cast<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: any): Types.Static<T>;
+}
Index: frontend/node_modules/@sinclair/typebox/value/cast.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/cast.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/cast.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,364 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueCast = exports.ValueCastUnknownTypeError = exports.ValueCastRecursiveTypeError = exports.ValueCastNeverTypeError = exports.ValueCastArrayUniqueItemsTypeError = exports.ValueCastReferenceTypeError = void 0;
+const Types = require("../typebox");
+const create_1 = require("./create");
+const check_1 = require("./check");
+const clone_1 = require("./clone");
+var UnionValueCast;
+(function (UnionValueCast) {
+    // ----------------------------------------------------------------------------------------------
+    // The following will score a schema against a value. For objects, the score is the tally of
+    // points awarded for each property of the value. Property points are (1.0 / propertyCount)
+    // to prevent large property counts biasing results. Properties that match literal values are
+    // maximally awarded as literals are typically used as union discriminator fields.
+    // ----------------------------------------------------------------------------------------------
+    function Score(schema, references, value) {
+        if (schema[Types.Kind] === 'Object' && typeof value === 'object' && value !== null) {
+            const object = schema;
+            const keys = Object.keys(value);
+            const entries = globalThis.Object.entries(object.properties);
+            const [point, max] = [1 / entries.length, entries.length];
+            return entries.reduce((acc, [key, schema]) => {
+                const literal = schema[Types.Kind] === 'Literal' && schema.const === value[key] ? max : 0;
+                const checks = check_1.ValueCheck.Check(schema, references, value[key]) ? point : 0;
+                const exists = keys.includes(key) ? point : 0;
+                return acc + (literal + checks + exists);
+            }, 0);
+        }
+        else {
+            return check_1.ValueCheck.Check(schema, references, value) ? 1 : 0;
+        }
+    }
+    function Select(union, references, value) {
+        let [select, best] = [union.anyOf[0], 0];
+        for (const schema of union.anyOf) {
+            const score = Score(schema, references, value);
+            if (score > best) {
+                select = schema;
+                best = score;
+            }
+        }
+        return select;
+    }
+    function Create(union, references, value) {
+        return check_1.ValueCheck.Check(union, references, value) ? clone_1.ValueClone.Clone(value) : ValueCast.Cast(Select(union, references, value), references, value);
+    }
+    UnionValueCast.Create = Create;
+})(UnionValueCast || (UnionValueCast = {}));
+// -----------------------------------------------------------
+// Errors
+// -----------------------------------------------------------
+class ValueCastReferenceTypeError extends Error {
+    constructor(schema) {
+        super(`ValueCast: Cannot locate referenced schema with $id '${schema.$ref}'`);
+        this.schema = schema;
+    }
+}
+exports.ValueCastReferenceTypeError = ValueCastReferenceTypeError;
+class ValueCastArrayUniqueItemsTypeError extends Error {
+    constructor(schema, value) {
+        super('ValueCast: Array cast produced invalid data due to uniqueItems constraint');
+        this.schema = schema;
+        this.value = value;
+    }
+}
+exports.ValueCastArrayUniqueItemsTypeError = ValueCastArrayUniqueItemsTypeError;
+class ValueCastNeverTypeError extends Error {
+    constructor(schema) {
+        super('ValueCast: Never types cannot be cast');
+        this.schema = schema;
+    }
+}
+exports.ValueCastNeverTypeError = ValueCastNeverTypeError;
+class ValueCastRecursiveTypeError extends Error {
+    constructor(schema) {
+        super('ValueCast.Recursive: Cannot cast recursive schemas');
+        this.schema = schema;
+    }
+}
+exports.ValueCastRecursiveTypeError = ValueCastRecursiveTypeError;
+class ValueCastUnknownTypeError extends Error {
+    constructor(schema) {
+        super('ValueCast: Unknown type');
+        this.schema = schema;
+    }
+}
+exports.ValueCastUnknownTypeError = ValueCastUnknownTypeError;
+var ValueCast;
+(function (ValueCast) {
+    // -----------------------------------------------------------
+    // Guards
+    // -----------------------------------------------------------
+    function IsArray(value) {
+        return typeof value === 'object' && globalThis.Array.isArray(value);
+    }
+    function IsString(value) {
+        return typeof value === 'string';
+    }
+    function IsBoolean(value) {
+        return typeof value === 'boolean';
+    }
+    function IsBigInt(value) {
+        return typeof value === 'bigint';
+    }
+    function IsNumber(value) {
+        return typeof value === 'number';
+    }
+    function IsStringNumeric(value) {
+        return IsString(value) && !isNaN(value) && !isNaN(parseFloat(value));
+    }
+    function IsValueToString(value) {
+        return IsBigInt(value) || IsBoolean(value) || IsNumber(value);
+    }
+    function IsValueTrue(value) {
+        return value === true || (IsNumber(value) && value === 1) || (IsBigInt(value) && value === 1n) || (IsString(value) && (value.toLowerCase() === 'true' || value === '1'));
+    }
+    function IsValueFalse(value) {
+        return value === false || (IsNumber(value) && value === 0) || (IsBigInt(value) && value === 0n) || (IsString(value) && (value.toLowerCase() === 'false' || value === '0'));
+    }
+    // -----------------------------------------------------------
+    // Convert
+    // -----------------------------------------------------------
+    function TryConvertString(value) {
+        return IsValueToString(value) ? value.toString() : value;
+    }
+    function TryConvertNumber(value) {
+        return IsStringNumeric(value) ? parseFloat(value) : IsValueTrue(value) ? 1 : value;
+    }
+    function TryConvertInteger(value) {
+        return IsStringNumeric(value) ? parseInt(value) : IsValueTrue(value) ? 1 : value;
+    }
+    function TryConvertBoolean(value) {
+        return IsValueTrue(value) ? true : IsValueFalse(value) ? false : value;
+    }
+    // -----------------------------------------------------------
+    // Cast
+    // -----------------------------------------------------------
+    function Any(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Array(schema, references, value) {
+        if (check_1.ValueCheck.Check(schema, references, value))
+            return clone_1.ValueClone.Clone(value);
+        const created = IsArray(value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references);
+        const minimum = IsNumber(schema.minItems) && created.length < schema.minItems ? [...created, ...globalThis.Array.from({ length: schema.minItems - created.length }, () => null)] : created;
+        const maximum = IsNumber(schema.maxItems) && minimum.length > schema.maxItems ? minimum.slice(0, schema.maxItems) : minimum;
+        const casted = maximum.map((value) => Visit(schema.items, references, value));
+        if (schema.uniqueItems !== true)
+            return casted;
+        const unique = [...new Set(casted)];
+        if (!check_1.ValueCheck.Check(schema, references, unique))
+            throw new ValueCastArrayUniqueItemsTypeError(schema, unique);
+        return unique;
+    }
+    function Boolean(schema, references, value) {
+        const conversion = TryConvertBoolean(value);
+        return check_1.ValueCheck.Check(schema, references, conversion) ? conversion : create_1.ValueCreate.Create(schema, references);
+    }
+    function Constructor(schema, references, value) {
+        if (check_1.ValueCheck.Check(schema, references, value))
+            return create_1.ValueCreate.Create(schema, references);
+        const required = new Set(schema.returns.required || []);
+        const result = function () { };
+        for (const [key, property] of globalThis.Object.entries(schema.returns.properties)) {
+            if (!required.has(key) && value.prototype[key] === undefined)
+                continue;
+            result.prototype[key] = Visit(property, references, value.prototype[key]);
+        }
+        return result;
+    }
+    function Enum(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Function(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Integer(schema, references, value) {
+        const conversion = TryConvertInteger(value);
+        return check_1.ValueCheck.Check(schema, references, conversion) ? conversion : create_1.ValueCreate.Create(schema, references);
+    }
+    function Literal(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Never(schema, references, value) {
+        throw new ValueCastNeverTypeError(schema);
+    }
+    function Null(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Number(schema, references, value) {
+        const conversion = TryConvertNumber(value);
+        return check_1.ValueCheck.Check(schema, references, conversion) ? conversion : create_1.ValueCreate.Create(schema, references);
+    }
+    function Object(schema, references, value) {
+        if (check_1.ValueCheck.Check(schema, references, value))
+            return clone_1.ValueClone.Clone(value);
+        if (value === null || typeof value !== 'object')
+            return create_1.ValueCreate.Create(schema, references);
+        const required = new Set(schema.required || []);
+        const result = {};
+        for (const [key, property] of globalThis.Object.entries(schema.properties)) {
+            if (!required.has(key) && value[key] === undefined)
+                continue;
+            result[key] = Visit(property, references, value[key]);
+        }
+        // additional schema properties
+        if (typeof schema.additionalProperties === 'object') {
+            const propertyKeys = globalThis.Object.keys(schema.properties);
+            for (const objectKey of globalThis.Object.keys(value)) {
+                if (propertyKeys.includes(objectKey))
+                    continue;
+                result[objectKey] = Visit(schema.additionalProperties, references, value[objectKey]);
+            }
+        }
+        return result;
+    }
+    function Promise(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Record(schema, references, value) {
+        if (check_1.ValueCheck.Check(schema, references, value))
+            return clone_1.ValueClone.Clone(value);
+        if (value === null || typeof value !== 'object' || globalThis.Array.isArray(value))
+            return create_1.ValueCreate.Create(schema, references);
+        const subschemaKey = globalThis.Object.keys(schema.patternProperties)[0];
+        const subschema = schema.patternProperties[subschemaKey];
+        const result = {};
+        for (const [propKey, propValue] of globalThis.Object.entries(value)) {
+            result[propKey] = Visit(subschema, references, propValue);
+        }
+        return result;
+    }
+    function Recursive(schema, references, value) {
+        throw new ValueCastRecursiveTypeError(schema);
+    }
+    function Ref(schema, references, value) {
+        const reference = references.find((reference) => reference.$id === schema.$ref);
+        if (reference === undefined)
+            throw new ValueCastReferenceTypeError(schema);
+        return Visit(reference, references, value);
+    }
+    function Self(schema, references, value) {
+        const reference = references.find((reference) => reference.$id === schema.$ref);
+        if (reference === undefined)
+            throw new ValueCastReferenceTypeError(schema);
+        return Visit(reference, references, value);
+    }
+    function String(schema, references, value) {
+        const conversion = TryConvertString(value);
+        return check_1.ValueCheck.Check(schema, references, conversion) ? conversion : create_1.ValueCreate.Create(schema, references);
+    }
+    function Tuple(schema, references, value) {
+        if (check_1.ValueCheck.Check(schema, references, value))
+            return clone_1.ValueClone.Clone(value);
+        if (!globalThis.Array.isArray(value))
+            return create_1.ValueCreate.Create(schema, references);
+        if (schema.items === undefined)
+            return [];
+        return schema.items.map((schema, index) => Visit(schema, references, value[index]));
+    }
+    function Undefined(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Union(schema, references, value) {
+        return UnionValueCast.Create(schema, references, value);
+    }
+    function Uint8Array(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Unknown(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Void(schema, references, value) {
+        return check_1.ValueCheck.Check(schema, references, value) ? value : create_1.ValueCreate.Create(schema, references);
+    }
+    function Visit(schema, references, value) {
+        const anyReferences = schema.$id === undefined ? references : [schema, ...references];
+        const anySchema = schema;
+        switch (schema[Types.Kind]) {
+            case 'Any':
+                return Any(anySchema, anyReferences, value);
+            case 'Array':
+                return Array(anySchema, anyReferences, value);
+            case 'Boolean':
+                return Boolean(anySchema, anyReferences, value);
+            case 'Constructor':
+                return Constructor(anySchema, anyReferences, value);
+            case 'Enum':
+                return Enum(anySchema, anyReferences, value);
+            case 'Function':
+                return Function(anySchema, anyReferences, value);
+            case 'Integer':
+                return Integer(anySchema, anyReferences, value);
+            case 'Literal':
+                return Literal(anySchema, anyReferences, value);
+            case 'Never':
+                return Never(anySchema, anyReferences, value);
+            case 'Null':
+                return Null(anySchema, anyReferences, value);
+            case 'Number':
+                return Number(anySchema, anyReferences, value);
+            case 'Object':
+                return Object(anySchema, anyReferences, value);
+            case 'Promise':
+                return Promise(anySchema, anyReferences, value);
+            case 'Record':
+                return Record(anySchema, anyReferences, value);
+            case 'Rec':
+                return Recursive(anySchema, anyReferences, value);
+            case 'Ref':
+                return Ref(anySchema, anyReferences, value);
+            case 'Self':
+                return Self(anySchema, anyReferences, value);
+            case 'String':
+                return String(anySchema, anyReferences, value);
+            case 'Tuple':
+                return Tuple(anySchema, anyReferences, value);
+            case 'Undefined':
+                return Undefined(anySchema, anyReferences, value);
+            case 'Union':
+                return Union(anySchema, anyReferences, value);
+            case 'Uint8Array':
+                return Uint8Array(anySchema, anyReferences, value);
+            case 'Unknown':
+                return Unknown(anySchema, anyReferences, value);
+            case 'Void':
+                return Void(anySchema, anyReferences, value);
+            default:
+                throw new ValueCastUnknownTypeError(anySchema);
+        }
+    }
+    ValueCast.Visit = Visit;
+    function Cast(schema, references, value) {
+        return schema.$id === undefined ? Visit(schema, references, value) : Visit(schema, [schema, ...references], value);
+    }
+    ValueCast.Cast = Cast;
+})(ValueCast = exports.ValueCast || (exports.ValueCast = {}));
Index: frontend/node_modules/@sinclair/typebox/value/check.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/check.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/check.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,8 @@
+import * as Types from '../typebox';
+export declare class ValueCheckUnknownTypeError extends Error {
+    readonly schema: Types.TSchema;
+    constructor(schema: Types.TSchema);
+}
+export declare namespace ValueCheck {
+    function Check<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: any): boolean;
+}
Index: frontend/node_modules/@sinclair/typebox/value/check.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/check.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/check.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,331 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueCheck = exports.ValueCheckUnknownTypeError = void 0;
+const Types = require("../typebox");
+const format_1 = require("../format");
+class ValueCheckUnknownTypeError extends Error {
+    constructor(schema) {
+        super('ValueCheck: Unknown type');
+        this.schema = schema;
+    }
+}
+exports.ValueCheckUnknownTypeError = ValueCheckUnknownTypeError;
+var ValueCheck;
+(function (ValueCheck) {
+    function Any(schema, references, value) {
+        return true;
+    }
+    function Array(schema, references, value) {
+        if (!globalThis.Array.isArray(value)) {
+            return false;
+        }
+        if (schema.minItems !== undefined && !(value.length >= schema.minItems)) {
+            return false;
+        }
+        if (schema.maxItems !== undefined && !(value.length <= schema.maxItems)) {
+            return false;
+        }
+        if (schema.uniqueItems === true && !(new Set(value).size === value.length)) {
+            return false;
+        }
+        return value.every((val) => Visit(schema.items, references, val));
+    }
+    function Boolean(schema, references, value) {
+        return typeof value === 'boolean';
+    }
+    function Constructor(schema, references, value) {
+        return Visit(schema.returns, references, value.prototype);
+    }
+    function Function(schema, references, value) {
+        return typeof value === 'function';
+    }
+    function Integer(schema, references, value) {
+        if (!(typeof value === 'number')) {
+            return false;
+        }
+        if (!globalThis.Number.isInteger(value)) {
+            return false;
+        }
+        if (schema.multipleOf !== undefined && !(value % schema.multipleOf === 0)) {
+            return false;
+        }
+        if (schema.exclusiveMinimum !== undefined && !(value > schema.exclusiveMinimum)) {
+            return false;
+        }
+        if (schema.exclusiveMaximum !== undefined && !(value < schema.exclusiveMaximum)) {
+            return false;
+        }
+        if (schema.minimum !== undefined && !(value >= schema.minimum)) {
+            return false;
+        }
+        if (schema.maximum !== undefined && !(value <= schema.maximum)) {
+            return false;
+        }
+        return true;
+    }
+    function Literal(schema, references, value) {
+        return value === schema.const;
+    }
+    function Never(schema, references, value) {
+        return false;
+    }
+    function Null(schema, references, value) {
+        return value === null;
+    }
+    function Number(schema, references, value) {
+        if (!(typeof value === 'number')) {
+            return false;
+        }
+        if (schema.multipleOf && !(value % schema.multipleOf === 0)) {
+            return false;
+        }
+        if (schema.exclusiveMinimum && !(value > schema.exclusiveMinimum)) {
+            return false;
+        }
+        if (schema.exclusiveMaximum && !(value < schema.exclusiveMaximum)) {
+            return false;
+        }
+        if (schema.minimum && !(value >= schema.minimum)) {
+            return false;
+        }
+        if (schema.maximum && !(value <= schema.maximum)) {
+            return false;
+        }
+        return true;
+    }
+    function Object(schema, references, value) {
+        if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
+            return false;
+        }
+        if (schema.minProperties !== undefined && !(globalThis.Object.keys(value).length >= schema.minProperties)) {
+            return false;
+        }
+        if (schema.maxProperties !== undefined && !(globalThis.Object.keys(value).length <= schema.maxProperties)) {
+            return false;
+        }
+        const propertyKeys = globalThis.Object.keys(schema.properties);
+        if (schema.additionalProperties === false) {
+            // optimization: If the property key length matches the required keys length
+            // then we only need check that the values property key length matches that
+            // of the property key length. This is because exhaustive testing for values
+            // will occur in subsequent property tests.
+            if (schema.required && schema.required.length === propertyKeys.length && !(globalThis.Object.keys(value).length === propertyKeys.length)) {
+                return false;
+            }
+            else {
+                if (!globalThis.Object.keys(value).every((key) => propertyKeys.includes(key))) {
+                    return false;
+                }
+            }
+        }
+        if (typeof schema.additionalProperties === 'object') {
+            for (const objectKey of globalThis.Object.keys(value)) {
+                if (propertyKeys.includes(objectKey))
+                    continue;
+                if (!Visit(schema.additionalProperties, references, value[objectKey])) {
+                    return false;
+                }
+            }
+        }
+        for (const propertyKey of propertyKeys) {
+            const propertySchema = schema.properties[propertyKey];
+            if (schema.required && schema.required.includes(propertyKey)) {
+                if (!Visit(propertySchema, references, value[propertyKey])) {
+                    return false;
+                }
+            }
+            else {
+                if (value[propertyKey] !== undefined) {
+                    if (!Visit(propertySchema, references, value[propertyKey])) {
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+    function Promise(schema, references, value) {
+        return typeof value === 'object' && typeof value.then === 'function';
+    }
+    function Record(schema, references, value) {
+        if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
+            return false;
+        }
+        const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
+        const regex = new RegExp(keyPattern);
+        if (!globalThis.Object.keys(value).every((key) => regex.test(key))) {
+            return false;
+        }
+        for (const propValue of globalThis.Object.values(value)) {
+            if (!Visit(valueSchema, references, propValue))
+                return false;
+        }
+        return true;
+    }
+    function Ref(schema, references, value) {
+        const reference = references.find((reference) => reference.$id === schema.$ref);
+        if (reference === undefined)
+            throw new Error(`ValueCheck.Ref: Cannot find schema with $id '${schema.$ref}'.`);
+        return Visit(reference, references, value);
+    }
+    function Self(schema, references, value) {
+        const reference = references.find((reference) => reference.$id === schema.$ref);
+        if (reference === undefined)
+            throw new Error(`ValueCheck.Self: Cannot find schema with $id '${schema.$ref}'.`);
+        return Visit(reference, references, value);
+    }
+    function String(schema, references, value) {
+        if (!(typeof value === 'string')) {
+            return false;
+        }
+        if (schema.minLength !== undefined) {
+            if (!(value.length >= schema.minLength))
+                return false;
+        }
+        if (schema.maxLength !== undefined) {
+            if (!(value.length <= schema.maxLength))
+                return false;
+        }
+        if (schema.pattern !== undefined) {
+            const regex = new RegExp(schema.pattern);
+            if (!regex.test(value))
+                return false;
+        }
+        if (schema.format !== undefined) {
+            if (!format_1.Format.Has(schema.format))
+                return false;
+            const func = format_1.Format.Get(schema.format);
+            return func(value);
+        }
+        return true;
+    }
+    function Tuple(schema, references, value) {
+        if (!globalThis.Array.isArray(value)) {
+            return false;
+        }
+        if (schema.items === undefined && !(value.length === 0)) {
+            return false;
+        }
+        if (!(value.length === schema.maxItems)) {
+            return false;
+        }
+        if (!schema.items) {
+            return true;
+        }
+        for (let i = 0; i < schema.items.length; i++) {
+            if (!Visit(schema.items[i], references, value[i]))
+                return false;
+        }
+        return true;
+    }
+    function Undefined(schema, references, value) {
+        return value === undefined;
+    }
+    function Union(schema, references, value) {
+        return schema.anyOf.some((inner) => Visit(inner, references, value));
+    }
+    function Uint8Array(schema, references, value) {
+        if (!(value instanceof globalThis.Uint8Array)) {
+            return false;
+        }
+        if (schema.maxByteLength && !(value.length <= schema.maxByteLength)) {
+            return false;
+        }
+        if (schema.minByteLength && !(value.length >= schema.minByteLength)) {
+            return false;
+        }
+        return true;
+    }
+    function Unknown(schema, references, value) {
+        return true;
+    }
+    function Void(schema, references, value) {
+        return value === null;
+    }
+    function Visit(schema, references, value) {
+        const anyReferences = schema.$id === undefined ? references : [schema, ...references];
+        const anySchema = schema;
+        switch (anySchema[Types.Kind]) {
+            case 'Any':
+                return Any(anySchema, anyReferences, value);
+            case 'Array':
+                return Array(anySchema, anyReferences, value);
+            case 'Boolean':
+                return Boolean(anySchema, anyReferences, value);
+            case 'Constructor':
+                return Constructor(anySchema, anyReferences, value);
+            case 'Function':
+                return Function(anySchema, anyReferences, value);
+            case 'Integer':
+                return Integer(anySchema, anyReferences, value);
+            case 'Literal':
+                return Literal(anySchema, anyReferences, value);
+            case 'Never':
+                return Never(anySchema, anyReferences, value);
+            case 'Null':
+                return Null(anySchema, anyReferences, value);
+            case 'Number':
+                return Number(anySchema, anyReferences, value);
+            case 'Object':
+                return Object(anySchema, anyReferences, value);
+            case 'Promise':
+                return Promise(anySchema, anyReferences, value);
+            case 'Record':
+                return Record(anySchema, anyReferences, value);
+            case 'Ref':
+                return Ref(anySchema, anyReferences, value);
+            case 'Self':
+                return Self(anySchema, anyReferences, value);
+            case 'String':
+                return String(anySchema, anyReferences, value);
+            case 'Tuple':
+                return Tuple(anySchema, anyReferences, value);
+            case 'Undefined':
+                return Undefined(anySchema, anyReferences, value);
+            case 'Union':
+                return Union(anySchema, anyReferences, value);
+            case 'Uint8Array':
+                return Uint8Array(anySchema, anyReferences, value);
+            case 'Unknown':
+                return Unknown(anySchema, anyReferences, value);
+            case 'Void':
+                return Void(anySchema, anyReferences, value);
+            default:
+                throw new ValueCheckUnknownTypeError(anySchema);
+        }
+    }
+    // -------------------------------------------------------------------------
+    // Check
+    // -------------------------------------------------------------------------
+    function Check(schema, references, value) {
+        return schema.$id === undefined ? Visit(schema, references, value) : Visit(schema, [schema, ...references], value);
+    }
+    ValueCheck.Check = Check;
+})(ValueCheck = exports.ValueCheck || (exports.ValueCheck = {}));
Index: frontend/node_modules/@sinclair/typebox/value/clone.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/clone.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/clone.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+export declare namespace ValueClone {
+    function Clone<T extends unknown>(value: T): T;
+}
Index: frontend/node_modules/@sinclair/typebox/value/clone.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/clone.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/clone.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,65 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueClone = void 0;
+const is_1 = require("./is");
+var ValueClone;
+(function (ValueClone) {
+    function Object(value) {
+        const keys = [...globalThis.Object.keys(value), ...globalThis.Object.getOwnPropertySymbols(value)];
+        return keys.reduce((acc, key) => ({ ...acc, [key]: Clone(value[key]) }), {});
+    }
+    function Array(value) {
+        return value.map((element) => Clone(element));
+    }
+    function TypedArray(value) {
+        return value.slice();
+    }
+    function Value(value) {
+        return value;
+    }
+    function Clone(value) {
+        if (is_1.Is.Object(value)) {
+            return Object(value);
+        }
+        else if (is_1.Is.Array(value)) {
+            return Array(value);
+        }
+        else if (is_1.Is.TypedArray(value)) {
+            return TypedArray(value);
+        }
+        else if (is_1.Is.Value(value)) {
+            return Value(value);
+        }
+        else {
+            throw new Error('ValueClone: Unable to clone value');
+        }
+    }
+    ValueClone.Clone = Clone;
+})(ValueClone = exports.ValueClone || (exports.ValueClone = {}));
Index: frontend/node_modules/@sinclair/typebox/value/create.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/create.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/create.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+import * as Types from '../typebox';
+export declare class ValueCreateUnknownTypeError extends Error {
+    readonly schema: Types.TSchema;
+    constructor(schema: Types.TSchema);
+}
+export declare class ValueCreateNeverTypeError extends Error {
+    readonly schema: Types.TSchema;
+    constructor(schema: Types.TSchema);
+}
+export declare namespace ValueCreate {
+    /** Creates a value from the given schema. If the schema specifies a default value, then that value is returned. */
+    function Visit<T extends Types.TSchema>(schema: T, references: Types.TSchema[]): Types.Static<T>;
+    function Create<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R]): Types.Static<T>;
+}
Index: frontend/node_modules/@sinclair/typebox/value/create.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/create.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/create.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,357 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueCreate = exports.ValueCreateNeverTypeError = exports.ValueCreateUnknownTypeError = void 0;
+const Types = require("../typebox");
+class ValueCreateUnknownTypeError extends Error {
+    constructor(schema) {
+        super('ValueCreate: Unknown type');
+        this.schema = schema;
+    }
+}
+exports.ValueCreateUnknownTypeError = ValueCreateUnknownTypeError;
+class ValueCreateNeverTypeError extends Error {
+    constructor(schema) {
+        super('ValueCreate: Never types cannot be created');
+        this.schema = schema;
+    }
+}
+exports.ValueCreateNeverTypeError = ValueCreateNeverTypeError;
+var ValueCreate;
+(function (ValueCreate) {
+    function Any(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            return {};
+        }
+    }
+    function Array(schema, references) {
+        if (schema.uniqueItems === true && schema.default === undefined) {
+            throw new Error('ValueCreate.Array: Arrays with uniqueItems require a default value');
+        }
+        else if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else if (schema.minItems !== undefined) {
+            return globalThis.Array.from({ length: schema.minItems }).map((item) => {
+                return ValueCreate.Create(schema.items, references);
+            });
+        }
+        else {
+            return [];
+        }
+    }
+    function Boolean(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            return false;
+        }
+    }
+    function Constructor(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            const value = ValueCreate.Create(schema.returns, references);
+            if (typeof value === 'object' && !globalThis.Array.isArray(value)) {
+                return class {
+                    constructor() {
+                        for (const [key, val] of globalThis.Object.entries(value)) {
+                            const self = this;
+                            self[key] = val;
+                        }
+                    }
+                };
+            }
+            else {
+                return class {
+                };
+            }
+        }
+    }
+    function Enum(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else if (schema.anyOf.length === 0) {
+            throw new Error('ValueCreate.Enum: Cannot create default enum value as this enum has no items');
+        }
+        else {
+            return schema.anyOf[0].const;
+        }
+    }
+    function Function(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            return () => ValueCreate.Create(schema.returns, references);
+        }
+    }
+    function Integer(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else if (schema.minimum !== undefined) {
+            return schema.minimum;
+        }
+        else {
+            return 0;
+        }
+    }
+    function Literal(schema, references) {
+        return schema.const;
+    }
+    function Never(schema, references) {
+        throw new ValueCreateNeverTypeError(schema);
+    }
+    function Null(schema, references) {
+        return null;
+    }
+    function Number(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else if (schema.minimum !== undefined) {
+            return schema.minimum;
+        }
+        else {
+            return 0;
+        }
+    }
+    function Object(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            const required = new Set(schema.required);
+            return (schema.default ||
+                globalThis.Object.entries(schema.properties).reduce((acc, [key, schema]) => {
+                    return required.has(key) ? { ...acc, [key]: ValueCreate.Create(schema, references) } : { ...acc };
+                }, {}));
+        }
+    }
+    function Promise(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            return globalThis.Promise.resolve(ValueCreate.Create(schema.item, references));
+        }
+    }
+    function Record(schema, references) {
+        const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else if (!(keyPattern === '^.*$' || keyPattern === '^(0|[1-9][0-9]*)$')) {
+            const propertyKeys = keyPattern.slice(1, keyPattern.length - 1).split('|');
+            return propertyKeys.reduce((acc, key) => {
+                return { ...acc, [key]: Create(valueSchema, references) };
+            }, {});
+        }
+        else {
+            return {};
+        }
+    }
+    function Recursive(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            throw new Error('ValueCreate.Recursive: Recursive types require a default value');
+        }
+    }
+    function Ref(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            const reference = references.find((reference) => reference.$id === schema.$ref);
+            if (reference === undefined)
+                throw new Error(`ValueCreate.Ref: Cannot find schema with $id '${schema.$ref}'.`);
+            return Visit(reference, references);
+        }
+    }
+    function Self(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            const reference = references.find((reference) => reference.$id === schema.$ref);
+            if (reference === undefined)
+                throw new Error(`ValueCreate.Self: Cannot locate schema with $id '${schema.$ref}'`);
+            return Visit(reference, references);
+        }
+    }
+    function String(schema, references) {
+        if (schema.pattern !== undefined) {
+            if (schema.default === undefined) {
+                throw new Error('ValueCreate.String: String types with patterns must specify a default value');
+            }
+            else {
+                return schema.default;
+            }
+        }
+        else if (schema.format !== undefined) {
+            if (schema.default === undefined) {
+                throw new Error('ValueCreate.String: String types with formats must specify a default value');
+            }
+            else {
+                return schema.default;
+            }
+        }
+        else {
+            if (schema.default !== undefined) {
+                return schema.default;
+            }
+            else if (schema.minLength !== undefined) {
+                return globalThis.Array.from({ length: schema.minLength })
+                    .map(() => '.')
+                    .join('');
+            }
+            else {
+                return '';
+            }
+        }
+    }
+    function Tuple(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        if (schema.items === undefined) {
+            return [];
+        }
+        else {
+            return globalThis.Array.from({ length: schema.minItems }).map((_, index) => ValueCreate.Create(schema.items[index], references));
+        }
+    }
+    function Undefined(schema, references) {
+        return undefined;
+    }
+    function Union(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else if (schema.anyOf.length === 0) {
+            throw new Error('ValueCreate.Union: Cannot create Union with zero variants');
+        }
+        else {
+            return ValueCreate.Create(schema.anyOf[0], references);
+        }
+    }
+    function Uint8Array(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else if (schema.minByteLength !== undefined) {
+            return new globalThis.Uint8Array(schema.minByteLength);
+        }
+        else {
+            return new globalThis.Uint8Array(0);
+        }
+    }
+    function Unknown(schema, references) {
+        if (schema.default !== undefined) {
+            return schema.default;
+        }
+        else {
+            return {};
+        }
+    }
+    function Void(schema, references) {
+        return null;
+    }
+    /** Creates a value from the given schema. If the schema specifies a default value, then that value is returned. */
+    function Visit(schema, references) {
+        const anyReferences = schema.$id === undefined ? references : [schema, ...references];
+        const anySchema = schema;
+        switch (anySchema[Types.Kind]) {
+            case 'Any':
+                return Any(anySchema, anyReferences);
+            case 'Array':
+                return Array(anySchema, anyReferences);
+            case 'Boolean':
+                return Boolean(anySchema, anyReferences);
+            case 'Constructor':
+                return Constructor(anySchema, anyReferences);
+            case 'Enum':
+                return Enum(anySchema, anyReferences);
+            case 'Function':
+                return Function(anySchema, anyReferences);
+            case 'Integer':
+                return Integer(anySchema, anyReferences);
+            case 'Literal':
+                return Literal(anySchema, anyReferences);
+            case 'Never':
+                return Never(anySchema, anyReferences);
+            case 'Null':
+                return Null(anySchema, anyReferences);
+            case 'Number':
+                return Number(anySchema, anyReferences);
+            case 'Object':
+                return Object(anySchema, anyReferences);
+            case 'Promise':
+                return Promise(anySchema, anyReferences);
+            case 'Record':
+                return Record(anySchema, anyReferences);
+            case 'Rec':
+                return Recursive(anySchema, anyReferences);
+            case 'Ref':
+                return Ref(anySchema, anyReferences);
+            case 'Self':
+                return Self(anySchema, anyReferences);
+            case 'String':
+                return String(anySchema, anyReferences);
+            case 'Tuple':
+                return Tuple(anySchema, anyReferences);
+            case 'Undefined':
+                return Undefined(anySchema, anyReferences);
+            case 'Union':
+                return Union(anySchema, anyReferences);
+            case 'Uint8Array':
+                return Uint8Array(anySchema, anyReferences);
+            case 'Unknown':
+                return Unknown(anySchema, anyReferences);
+            case 'Void':
+                return Void(anySchema, anyReferences);
+            default:
+                throw new ValueCreateUnknownTypeError(anySchema);
+        }
+    }
+    ValueCreate.Visit = Visit;
+    function Create(schema, references) {
+        return Visit(schema, references);
+    }
+    ValueCreate.Create = Create;
+})(ValueCreate = exports.ValueCreate || (exports.ValueCreate = {}));
Index: frontend/node_modules/@sinclair/typebox/value/delta.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/delta.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/delta.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,22 @@
+export declare type Edit<T = unknown> = Insert<T> | Update<T> | Delete<T>;
+export interface Insert<T> {
+    brand: T;
+    type: 'insert';
+    path: string;
+    value: any;
+}
+export interface Update<T> {
+    brand: T;
+    type: 'update';
+    path: string;
+    value: any;
+}
+export interface Delete<T> {
+    brand: T;
+    type: 'delete';
+    path: string;
+}
+export declare namespace ValueDelta {
+    function Diff<T>(current: T, next: T): Edit<T>[];
+    function Patch<T>(current: T, edits: Edit<T>[]): T;
+}
Index: frontend/node_modules/@sinclair/typebox/value/delta.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/delta.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/delta.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,168 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueDelta = void 0;
+const is_1 = require("./is");
+const clone_1 = require("./clone");
+const pointer_1 = require("./pointer");
+var ValueDelta;
+(function (ValueDelta) {
+    // ---------------------------------------------------------------------
+    // Edits
+    // ---------------------------------------------------------------------
+    function Update(path, value) {
+        return { type: 'update', path, value };
+    }
+    function Insert(path, value) {
+        return { type: 'insert', path, value };
+    }
+    function Delete(path) {
+        return { type: 'delete', path };
+    }
+    // ---------------------------------------------------------------------
+    // Diff
+    // ---------------------------------------------------------------------
+    function* Object(path, current, next) {
+        if (!is_1.Is.Object(next))
+            return yield Update(path, next);
+        const currentKeys = [...globalThis.Object.keys(current), ...globalThis.Object.getOwnPropertySymbols(current)];
+        const nextKeys = [...globalThis.Object.keys(next), ...globalThis.Object.getOwnPropertySymbols(next)];
+        for (const key of currentKeys) {
+            if (typeof key === 'symbol')
+                throw Error('ValueDelta: Cannot produce diff symbol keys');
+            if (next[key] === undefined && nextKeys.includes(key))
+                yield Update(`${path}/${String(key)}`, undefined);
+        }
+        for (const key of nextKeys) {
+            if (current[key] === undefined || next[key] === undefined)
+                continue;
+            if (typeof key === 'symbol')
+                throw Error('ValueDelta: Cannot produce diff symbol keys');
+            yield* Visit(`${path}/${String(key)}`, current[key], next[key]);
+        }
+        for (const key of nextKeys) {
+            if (typeof key === 'symbol')
+                throw Error('ValueDelta: Cannot produce diff symbol keys');
+            if (current[key] === undefined)
+                yield Insert(`${path}/${String(key)}`, next[key]);
+        }
+        for (const key of currentKeys.reverse()) {
+            if (typeof key === 'symbol')
+                throw Error('ValueDelta: Cannot produce diff symbol keys');
+            if (next[key] === undefined && !nextKeys.includes(key))
+                yield Delete(`${path}/${String(key)}`);
+        }
+    }
+    function* Array(path, current, next) {
+        if (!is_1.Is.Array(next))
+            return yield Update(path, next);
+        for (let i = 0; i < Math.min(current.length, next.length); i++) {
+            yield* Visit(`${path}/${i}`, current[i], next[i]);
+        }
+        for (let i = 0; i < next.length; i++) {
+            if (i < current.length)
+                continue;
+            yield Insert(`${path}/${i}`, next[i]);
+        }
+        for (let i = current.length - 1; i >= 0; i--) {
+            if (i < next.length)
+                continue;
+            yield Delete(`${path}/${i}`);
+        }
+    }
+    function* TypedArray(path, current, next) {
+        if (!is_1.Is.TypedArray(next) || current.length !== next.length || globalThis.Object.getPrototypeOf(current).constructor.name !== globalThis.Object.getPrototypeOf(next).constructor.name)
+            return yield Update(path, next);
+        for (let i = 0; i < Math.min(current.length, next.length); i++) {
+            yield* Visit(`${path}/${i}`, current[i], next[i]);
+        }
+    }
+    function* Value(path, current, next) {
+        if (current === next)
+            return;
+        yield Update(path, next);
+    }
+    function* Visit(path, current, next) {
+        if (is_1.Is.Object(current)) {
+            return yield* Object(path, current, next);
+        }
+        else if (is_1.Is.Array(current)) {
+            return yield* Array(path, current, next);
+        }
+        else if (is_1.Is.TypedArray(current)) {
+            return yield* TypedArray(path, current, next);
+        }
+        else if (is_1.Is.Value(current)) {
+            return yield* Value(path, current, next);
+        }
+        else {
+            throw new Error('ValueDelta: Cannot produce edits for value');
+        }
+    }
+    function Diff(current, next) {
+        return [...Visit('', current, next)];
+    }
+    ValueDelta.Diff = Diff;
+    // ---------------------------------------------------------------------
+    // Patch
+    // ---------------------------------------------------------------------
+    function IsRootUpdate(edits) {
+        return edits.length > 0 && edits[0].path === '' && edits[0].type === 'update';
+    }
+    function IsIdentity(edits) {
+        return edits.length === 0;
+    }
+    function Patch(current, edits) {
+        if (IsRootUpdate(edits)) {
+            return clone_1.ValueClone.Clone(edits[0].value);
+        }
+        if (IsIdentity(edits)) {
+            return clone_1.ValueClone.Clone(current);
+        }
+        const clone = clone_1.ValueClone.Clone(current);
+        for (const edit of edits) {
+            switch (edit.type) {
+                case 'insert': {
+                    pointer_1.ValuePointer.Set(clone, edit.path, edit.value);
+                    break;
+                }
+                case 'update': {
+                    pointer_1.ValuePointer.Set(clone, edit.path, edit.value);
+                    break;
+                }
+                case 'delete': {
+                    pointer_1.ValuePointer.Delete(clone, edit.path);
+                    break;
+                }
+            }
+        }
+        return clone;
+    }
+    ValueDelta.Patch = Patch;
+})(ValueDelta = exports.ValueDelta || (exports.ValueDelta = {}));
Index: frontend/node_modules/@sinclair/typebox/value/equal.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/equal.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/equal.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+export declare namespace ValueEqual {
+    function Equal<T>(left: T, right: unknown): right is T;
+}
Index: frontend/node_modules/@sinclair/typebox/value/equal.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/equal.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/equal.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,74 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueEqual = void 0;
+const is_1 = require("./is");
+var ValueEqual;
+(function (ValueEqual) {
+    function Object(left, right) {
+        if (!is_1.Is.Object(right))
+            return false;
+        const leftKeys = [...globalThis.Object.keys(left), ...globalThis.Object.getOwnPropertySymbols(left)];
+        const rightKeys = [...globalThis.Object.keys(right), ...globalThis.Object.getOwnPropertySymbols(right)];
+        if (leftKeys.length !== rightKeys.length)
+            return false;
+        return leftKeys.every((key) => Equal(left[key], right[key]));
+    }
+    function Array(left, right) {
+        if (!is_1.Is.Array(right) || left.length !== right.length)
+            return false;
+        return left.every((value, index) => Equal(value, right[index]));
+    }
+    function TypedArray(left, right) {
+        if (!is_1.Is.TypedArray(right) || left.length !== right.length || globalThis.Object.getPrototypeOf(left).constructor.name !== globalThis.Object.getPrototypeOf(right).constructor.name)
+            return false;
+        return left.every((value, index) => Equal(value, right[index]));
+    }
+    function Value(left, right) {
+        return left === right;
+    }
+    function Equal(left, right) {
+        if (is_1.Is.Object(left)) {
+            return Object(left, right);
+        }
+        else if (is_1.Is.TypedArray(left)) {
+            return TypedArray(left, right);
+        }
+        else if (is_1.Is.Array(left)) {
+            return Array(left, right);
+        }
+        else if (is_1.Is.Value(left)) {
+            return Value(left, right);
+        }
+        else {
+            throw new Error('ValueEquals: Unable to compare value');
+        }
+    }
+    ValueEqual.Equal = Equal;
+})(ValueEqual = exports.ValueEqual || (exports.ValueEqual = {}));
Index: frontend/node_modules/@sinclair/typebox/value/index.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+export { ValueError, ValueErrorType } from '../errors/index';
+export * from './pointer';
+export * from './value';
Index: frontend/node_modules/@sinclair/typebox/value/index.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,48 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueErrorType = void 0;
+var index_1 = require("../errors/index");
+Object.defineProperty(exports, "ValueErrorType", { enumerable: true, get: function () { return index_1.ValueErrorType; } });
+__exportStar(require("./pointer"), exports);
+__exportStar(require("./value"), exports);
Index: frontend/node_modules/@sinclair/typebox/value/is.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/is.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/is.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,10 @@
+export declare type ValueType = null | undefined | Function | symbol | bigint | number | boolean | string;
+export declare type ObjectType = Record<string | number | symbol, unknown>;
+export declare type TypedArrayType = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
+export declare type ArrayType = unknown[];
+export declare namespace Is {
+    function Object(value: unknown): value is ObjectType;
+    function Array(value: unknown): value is ArrayType;
+    function Value(value: unknown): value is ValueType;
+    function TypedArray(value: unknown): value is TypedArrayType;
+}
Index: frontend/node_modules/@sinclair/typebox/value/is.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/is.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/is.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,49 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Is = void 0;
+var Is;
+(function (Is) {
+    function Object(value) {
+        return value !== null && typeof value === 'object' && !globalThis.Array.isArray(value) && !ArrayBuffer.isView(value);
+    }
+    Is.Object = Object;
+    function Array(value) {
+        return globalThis.Array.isArray(value) && !ArrayBuffer.isView(value);
+    }
+    Is.Array = Array;
+    function Value(value) {
+        return value === null || value === undefined || typeof value === 'function' || typeof value === 'symbol' || typeof value === 'bigint' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string';
+    }
+    Is.Value = Value;
+    function TypedArray(value) {
+        return ArrayBuffer.isView(value);
+    }
+    Is.TypedArray = TypedArray;
+})(Is = exports.Is || (exports.Is = {}));
Index: frontend/node_modules/@sinclair/typebox/value/pointer.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/pointer.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/pointer.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,24 @@
+export declare class ValuePointerRootSetError extends Error {
+    readonly value: unknown;
+    readonly path: string;
+    readonly update: unknown;
+    constructor(value: unknown, path: string, update: unknown);
+}
+export declare class ValuePointerRootDeleteError extends Error {
+    readonly value: unknown;
+    readonly path: string;
+    constructor(value: unknown, path: string);
+}
+/** ValuePointer performs mutable operations on values using RFC6901 Json Pointers */
+export declare namespace ValuePointer {
+    /** Formats the given pointer into navigable key components */
+    function Format(pointer: string): IterableIterator<string>;
+    /** Sets the value at the given pointer. If the value at the pointer does not exist it is created */
+    function Set(value: any, pointer: string, update: unknown): void;
+    /** Deletes a value at the given pointer */
+    function Delete(value: any, pointer: string): void;
+    /** Returns true if a value exists at the given pointer */
+    function Has(value: any, pointer: string): boolean;
+    /** Gets the value at the given pointer */
+    function Get(value: any, pointer: string): any;
+}
Index: frontend/node_modules/@sinclair/typebox/value/pointer.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/pointer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/pointer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,142 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValuePointer = exports.ValuePointerRootDeleteError = exports.ValuePointerRootSetError = void 0;
+class ValuePointerRootSetError extends Error {
+    constructor(value, path, update) {
+        super('ValuePointer: Cannot set root value');
+        this.value = value;
+        this.path = path;
+        this.update = update;
+    }
+}
+exports.ValuePointerRootSetError = ValuePointerRootSetError;
+class ValuePointerRootDeleteError extends Error {
+    constructor(value, path) {
+        super('ValuePointer: Cannot delete root value');
+        this.value = value;
+        this.path = path;
+    }
+}
+exports.ValuePointerRootDeleteError = ValuePointerRootDeleteError;
+/** ValuePointer performs mutable operations on values using RFC6901 Json Pointers */
+var ValuePointer;
+(function (ValuePointer) {
+    function Escape(component) {
+        return component.indexOf('~') === -1 ? component : component.replace(/~1/g, '/').replace(/~0/g, '~');
+    }
+    /** Formats the given pointer into navigable key components */
+    function* Format(pointer) {
+        if (pointer === '')
+            return;
+        let [start, end] = [0, 0];
+        for (let i = 0; i < pointer.length; i++) {
+            const char = pointer.charAt(i);
+            if (char === '/') {
+                if (i === 0) {
+                    start = i + 1;
+                }
+                else {
+                    end = i;
+                    yield Escape(pointer.slice(start, end));
+                    start = i + 1;
+                }
+            }
+            else {
+                end = i;
+            }
+        }
+        yield Escape(pointer.slice(start));
+    }
+    ValuePointer.Format = Format;
+    /** Sets the value at the given pointer. If the value at the pointer does not exist it is created */
+    function Set(value, pointer, update) {
+        if (pointer === '')
+            throw new ValuePointerRootSetError(value, pointer, update);
+        let [owner, next, key] = [null, value, ''];
+        for (const component of Format(pointer)) {
+            if (next[component] === undefined)
+                next[component] = {};
+            owner = next;
+            next = next[component];
+            key = component;
+        }
+        owner[key] = update;
+    }
+    ValuePointer.Set = Set;
+    /** Deletes a value at the given pointer */
+    function Delete(value, pointer) {
+        if (pointer === '')
+            throw new ValuePointerRootDeleteError(value, pointer);
+        let [owner, next, key] = [null, value, ''];
+        for (const component of Format(pointer)) {
+            if (next[component] === undefined || next[component] === null)
+                return;
+            owner = next;
+            next = next[component];
+            key = component;
+        }
+        if (globalThis.Array.isArray(owner)) {
+            const index = parseInt(key);
+            owner.splice(index, 1);
+        }
+        else {
+            delete owner[key];
+        }
+    }
+    ValuePointer.Delete = Delete;
+    /** Returns true if a value exists at the given pointer */
+    function Has(value, pointer) {
+        if (pointer === '')
+            return true;
+        let [owner, next, key] = [null, value, ''];
+        for (const component of Format(pointer)) {
+            if (next[component] === undefined)
+                return false;
+            owner = next;
+            next = next[component];
+            key = component;
+        }
+        return globalThis.Object.getOwnPropertyNames(owner).includes(key);
+    }
+    ValuePointer.Has = Has;
+    /** Gets the value at the given pointer */
+    function Get(value, pointer) {
+        if (pointer === '')
+            return value;
+        let current = value;
+        for (const component of Format(pointer)) {
+            if (current[component] === undefined)
+                return undefined;
+            current = current[component];
+        }
+        return current;
+    }
+    ValuePointer.Get = Get;
+})(ValuePointer = exports.ValuePointer || (exports.ValuePointer = {}));
Index: frontend/node_modules/@sinclair/typebox/value/value.d.ts
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/value.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/value.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,31 @@
+import * as Types from '../typebox';
+import { ValueError } from '../errors/index';
+import { Edit } from './delta';
+export type { Edit } from './delta';
+/** Value performs immutable operations on values */
+export declare namespace Value {
+    /** Casts a value into a given type. The return value will retain as much information of the original value as possible. Cast will convert string, number and boolean values if a reasonable conversion is possible. */
+    function Cast<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: unknown): Types.Static<T>;
+    /** Casts a value into a given type. The return value will retain as much information of the original value as possible. Cast will convert string, number and boolean values if a reasonable conversion is possible. */
+    function Cast<T extends Types.TSchema>(schema: T, value: unknown): Types.Static<T>;
+    /** Creates a value from the given type */
+    function Create<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R]): Types.Static<T>;
+    /** Creates a value from the given type */
+    function Create<T extends Types.TSchema>(schema: T): Types.Static<T>;
+    /** Returns true if the value matches the given type. */
+    function Check<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: unknown): value is Types.Static<T>;
+    /** Returns true if the value matches the given type. */
+    function Check<T extends Types.TSchema>(schema: T, value: unknown): value is Types.Static<T>;
+    /** Returns an iterator for each error in this value. */
+    function Errors<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: unknown): IterableIterator<ValueError>;
+    /** Returns an iterator for each error in this value. */
+    function Errors<T extends Types.TSchema>(schema: T, value: unknown): IterableIterator<ValueError>;
+    /** Returns true if left and right values are structurally equal */
+    function Equal<T>(left: T, right: unknown): right is T;
+    /** Returns a structural clone of the given value */
+    function Clone<T>(value: T): T;
+    /** Returns edits to transform the current value into the next value */
+    function Diff<T>(current: T, next: T): Edit<T>[];
+    /** Returns a new value with edits applied to the given value */
+    function Patch<T>(current: T, edits: Edit<T>[]): T;
+}
Index: frontend/node_modules/@sinclair/typebox/value/value.js
===================================================================
--- frontend/node_modules/@sinclair/typebox/value/value.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@sinclair/typebox/value/value.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,81 @@
+"use strict";
+/*--------------------------------------------------------------------------
+
+@sinclair/typebox/value
+
+The MIT License (MIT)
+
+Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+---------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Value = void 0;
+const index_1 = require("../errors/index");
+const equal_1 = require("./equal");
+const cast_1 = require("./cast");
+const clone_1 = require("./clone");
+const create_1 = require("./create");
+const check_1 = require("./check");
+const delta_1 = require("./delta");
+/** Value performs immutable operations on values */
+var Value;
+(function (Value) {
+    function Cast(...args) {
+        const [schema, references, value] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], [], args[1]];
+        return cast_1.ValueCast.Cast(schema, references, value);
+    }
+    Value.Cast = Cast;
+    function Create(...args) {
+        const [schema, references] = args.length === 2 ? [args[0], args[1]] : [args[0], []];
+        return create_1.ValueCreate.Create(schema, references);
+    }
+    Value.Create = Create;
+    function Check(...args) {
+        const [schema, references, value] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], [], args[1]];
+        return check_1.ValueCheck.Check(schema, references, value);
+    }
+    Value.Check = Check;
+    function* Errors(...args) {
+        const [schema, references, value] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], [], args[1]];
+        yield* index_1.ValueErrors.Errors(schema, references, value);
+    }
+    Value.Errors = Errors;
+    /** Returns true if left and right values are structurally equal */
+    function Equal(left, right) {
+        return equal_1.ValueEqual.Equal(left, right);
+    }
+    Value.Equal = Equal;
+    /** Returns a structural clone of the given value */
+    function Clone(value) {
+        return clone_1.ValueClone.Clone(value);
+    }
+    Value.Clone = Clone;
+    /** Returns edits to transform the current value into the next value */
+    function Diff(current, next) {
+        return delta_1.ValueDelta.Diff(current, next);
+    }
+    Value.Diff = Diff;
+    /** Returns a new value with edits applied to the given value */
+    function Patch(current, edits) {
+        return delta_1.ValueDelta.Patch(current, edits);
+    }
+    Value.Patch = Patch;
+})(Value = exports.Value || (exports.Value = {}));
