Compare commits

...

7 Commits

58 changed files with 2619 additions and 0 deletions

3
.gitignore vendored
View File

@ -43,6 +43,9 @@ build/Release
node_modules/ node_modules/
jspm_packages/ jspm_packages/
# Builds
build/
# Snowpack dependency directory (https://snowpack.dev/) # Snowpack dependency directory (https://snowpack.dev/)
web_modules/ web_modules/

21
default.code-workspace Normal file
View File

@ -0,0 +1,21 @@
{
"folders": [
{
"name": "RayLab Root",
"path": "./"
},
{
"name": "Virtual Renderer",
"path": "./packages/renderer-virtual"
},
{
"name": "WebGL Renderer",
"path": "./packages/renderer-webgl"
},
{
"name": "WebGL Debugger",
"path": "./packages/renderer-debugger"
}
],
"settings": {}
}

2
engine/RayLab.ts Normal file
View File

@ -0,0 +1,2 @@
export { Vector2D, Vector3D, Vector4D } from "@engine/math"
export { TreeNode } from "@engine/kernel"

1
engine/kernel/Kernel.ts Normal file
View File

@ -0,0 +1 @@
export { TreeNode } from "./TreeNode";

234
engine/kernel/TreeNode.ts Normal file
View File

@ -0,0 +1,234 @@
/**
* A tree type data structure used to build scene and ...
* @copyright MrKBear 2022
* @typeParam T - Child type of `TreeNode`
*/
class TreeNode<T extends TreeNode = TreeNode<any>> implements Iterable<T> {
/**
* Record all child nodes when this node is the root node.
* @remarks
* Only maintained when the node is the root node. \
* The array is arranged in depth first traversal order.
*/
private _progenyNodes: Array<T> | undefined = [ ];
/**
* Whether the structure of the current tree has changed.
* @remarks
* Only maintained when the node is the root node.
*/
private _isStructUpdated = false;
/**
* @remarks
* When a node is just created, it defaults the root node. \
* So this `rootNode` points to itself.
*/
private _rootNode: T | this = this;
private _parentNode: T | undefined = void 0;
private _childNodes: Array<T> = [];
/**
* Pointer to the root node.
*/
public get rootNode(): T | this { return this._rootNode; }
/**
* Pointer to the parent node.
*/
public get parentNode(): T | undefined { return this._parentNode; }
/**
* Points to the children of the current node.
*/
public get childNodes(): ReadonlyArray<T> { return this._childNodes; }
/**
* Is this a root node?
*/
public get isRootNode(): boolean { return !this._parentNode && this._rootNode === this; }
/**
* Depth first traverses the current `TreeNode` and its children `TreeNode`.
* @remarks
* This will use {@link https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR Pre-order (NLR) algorithm}. \
* So... Do not call this getter frequently.
* @example
* ``` javascript
* // ❌ Deprecated implementation !!!
* for (let i = 0; i < treeNode.progenyNodes.length; i++) {
* doSomeThing(treeNode.progenyNodes[i]);
* }
*
* // ✔️ Best Practices
* treeNode.progenyNodes.forEach((progenyNode)=> {
* doSomeThing(progenyNode);
* });
*
* // ✔️ Best Practices
* for(const progenyNode of treeNode.progenyNodes) {
* doSomeThing(progenyNode);
* }
* ```
* @return Progeny nodes list.
*/
public get progenyNodes(): ReadonlyArray<T> {
if (this.isRootNode && !this._isStructUpdated && this._progenyNodes) {
return this._progenyNodes;
}
else {
const cacheArray: Array<T> = [];
const stack: Array<T> = this._childNodes.slice().reverse();
while (stack.length > 0) {
const currentNode: T | undefined = stack.pop();
if (currentNode) {
cacheArray.push(currentNode);
// Push all child nodes in reverse order
for (let i = currentNode.childNodes.length - 1; i >= 0; i --) {
stack.push(<T>currentNode.childNodes[i]);
}
}
}
if (this.isRootNode) {
this._progenyNodes = cacheArray;
this._isStructUpdated = false;
}
return cacheArray;
}
}
/**
* An iterator implementation for {@link TreeNode.progenyNodes}
* @see {@link TreeNode.progenyNodes}
*/
public *[Symbol.iterator](): Iterator<T> { yield * this.progenyNodes; }
/**
* Remove `nodes` from child nodes.
* @param nodes - Nodes to be deleted.
* @returns Success Times.
*/
public removeChild(...nodes: ReadonlyArray<T>): number {
let successCount = 0;
for (const node of nodes) {
let removeNodesIndex = -1;
for (let i = 0; i < this._childNodes.length; i++) {
if (this._childNodes[i] === node) {
removeNodesIndex = i;
}
}
if (removeNodesIndex < 0) {
continue;
}
// Perform the remove operation
this._childNodes.splice(removeNodesIndex, 1);
node._parentNode = void 0;
node._rootNode = node;
node.markStructUpdated();
for (const progeny of node.progenyNodes) {
progeny._rootNode = node;
}
successCount ++;
}
if (successCount) {
this._rootNode.markStructUpdated();
}
return successCount;
}
/**
* Remove this node from the parent node
* @returns Success or not.
*/
public removeFromParent(): number {
if (this.isRootNode) {
return 0;
}
else {
return this._parentNode!.removeChild(this);
}
}
/**
* Append `nodes` into child nodes.
* @param node - Nodes to be added.
* @returns Success Times.
*/
public appendChild(...nodes: ReadonlyArray<T>): number {
let successCount = 0;
for (const node of nodes) {
if (!node.isRootNode) {
node.removeFromParent();
}
for (const progeny of node.progenyNodes) {
progeny._rootNode = this._rootNode;
}
node._rootNode = this._rootNode;
node._parentNode = this;
node._progenyNodes = void 0;
this._childNodes.push(node);
successCount ++;
}
if (successCount) {
this._rootNode.markStructUpdated();
}
return successCount;
}
/**
* Mark that the current tree structure has been updated
* @returns true
*/
public markStructUpdated(): boolean {
if (this.isRootNode) {
return this._isStructUpdated = true;
}
else {
return this.rootNode.markStructUpdated();
}
}
}
class B extends TreeNode<B> { b(){}; }
class A extends TreeNode<A> { a(){}; }
class C extends A { c(){}; }
const a = new A();
const b = new B();
const c = new C();
a.rootNode.rootNode.appendChild(c);
// a.rootNode.rootNode.appendChild(a);
console.log(a);
export { TreeNode };

3
engine/math/Math.ts Normal file
View File

@ -0,0 +1,3 @@
export { Vector2D } from "./Vector2D";
export { Vector3D } from "./Vector3D";
export { Vector4D } from "./Vector4D";

View File

@ -0,0 +1,54 @@
/**
* Type of update status can be recorded
* An update flag is used here to implement data lazy calculation
* @copyright MrKBear 2022
*/
abstract class UpdatedRecorder {
/**
* The flag for recorded update status
* @defaultValue `true`
*/
protected updateFlag: boolean = true;
/**
* Initialize and set the default update status
* @param updateFlag update status
*/
public constructor(updateFlag: boolean = true) {
this.updateFlag = updateFlag;
}
/**
* Return the update status
* @returns update status
*/
public isUpdated(): boolean {
return this.updateFlag;
}
/**
* Set update status `false`
* @returns update status
*/
public unsetUpdated(): false {
return this.updateFlag = false;
}
/**
* Automatically detect and reset update status
* @returns update status
*/
public testAndUnsetUpdate(): boolean {
if (this.updateFlag) {
this.updateFlag = false;
return true;
}
else {
return false;
}
}
}
export { UpdatedRecorder };

83
engine/math/Vector2D.ts Normal file
View File

@ -0,0 +1,83 @@
import { UpdatedRecorder } from "./UpdatedRecorder";
/**
* A vector with two dimensions
*/
class Vector2D extends UpdatedRecorder implements ArrayLike<number>, Iterable<number> {
private value0: number = 0;
private value1: number = 0;
readonly [n: number]: number;
/**
* Vector length
*/
public get length(): number {
return 2;
};
public override toString(): string {
return `Vector2D(${this.value0},${this.value1})`;
}
/**
* Enumerate this vector
*/
public *[Symbol.iterator](): Iterator<number> {
yield this.value0;
yield this.value1;
}
/**
* The first component of this vector
*/
public get [0](): number {
return this.value0;
}
public set [0](newValue: number) {
if (!this.updateFlag && this.value0 !== newValue) {
this.updateFlag = true;
}
this.value0 = newValue;
}
/**
* The second component of this vector
*/
public get [1](): number {
return this.value1;
}
public set [1](newValue: number) {
if (!this.updateFlag && this.value1 !== newValue) {
this.updateFlag = true;
}
this.value1 = newValue;
}
/**
* X component of the vector
*/
public get x(): number {
return this.value0;
}
public set x(newValue: number) {
this[0] = newValue;
}
/**
* Y component of the vector
*/
public get y(): number {
return this.value1;
}
public set y(newValue: number) {
this[1] = newValue;
}
}
export { Vector2D };

110
engine/math/Vector3D.ts Normal file
View File

@ -0,0 +1,110 @@
import { UpdatedRecorder } from "./UpdatedRecorder";
/**
* A vector with three dimensions
*/
class Vector3D extends UpdatedRecorder implements ArrayLike<number>, Iterable<number> {
private value0: number = 0;
private value1: number = 0;
private value2: number = 0;
readonly [n: number]: number;
/**
* Vector length
*/
public get length(): number {
return 3;
};
public override toString(): string {
return `Vector3D(${this.value0},${this.value1},${this.value2})`;
}
/**
* Enumerate this vector
*/
public *[Symbol.iterator](): Iterator<number> {
yield this.value0;
yield this.value1;
yield this.value2;
}
/**
* The first component of this vector
*/
public get [0](): number {
return this.value0;
}
public set [0](newValue: number) {
if (!this.updateFlag && this.value0 !== newValue) {
this.updateFlag = true;
}
this.value0 = newValue;
}
/**
* The second component of this vector
*/
public get [1](): number {
return this.value1;
}
public set [1](newValue: number) {
if (!this.updateFlag && this.value1 !== newValue) {
this.updateFlag = true;
}
this.value1 = newValue;
}
/**
* The third component of this vector
*/
public get [2](): number {
return this.value2;
}
public set [2](newValue: number) {
if (!this.updateFlag && this.value2 !== newValue) {
this.updateFlag = true;
}
this.value2 = newValue;
}
/**
* X component of the vector
*/
public get x(): number {
return this.value0;
}
public set x(newValue: number) {
this[0] = newValue;
}
/**
* Y component of the vector
*/
public get y(): number {
return this.value1;
}
public set y(newValue: number) {
this[1] = newValue;
}
/**
* Z component of the vector
*/
public get z(): number {
return this.value2;
}
public set z(newValue: number) {
this[2] = newValue;
}
}
export { Vector3D };

137
engine/math/Vector4D.ts Normal file
View File

@ -0,0 +1,137 @@
import { UpdatedRecorder } from "./UpdatedRecorder";
/**
* A vector with four dimensions
*/
class Vector4D extends UpdatedRecorder implements ArrayLike<number>, Iterable<number> {
private value0: number = 0;
private value1: number = 0;
private value2: number = 0;
private value3: number = 0;
readonly [n: number]: number;
/**
* Vector length
*/
public get length(): number {
return 4;
};
public override toString(): string {
return `Vector4D(${this.value0},${this.value1},${this.value2},${this.value3})`;
}
/**
* Enumerate this vector
*/
public *[Symbol.iterator](): Iterator<number> {
yield this.value0;
yield this.value1;
yield this.value2;
yield this.value3;
}
/**
* The first component of this vector
*/
public get [0](): number {
return this.value0;
}
public set [0](newValue: number) {
if (!this.updateFlag && this.value0 !== newValue) {
this.updateFlag = true;
}
this.value0 = newValue;
}
/**
* The second component of this vector
*/
public get [1](): number {
return this.value1;
}
public set [1](newValue: number) {
if (!this.updateFlag && this.value1 !== newValue) {
this.updateFlag = true;
}
this.value1 = newValue;
}
/**
* The third component of this vector
*/
public get [2](): number {
return this.value2;
}
public set [2](newValue: number) {
if (!this.updateFlag && this.value2 !== newValue) {
this.updateFlag = true;
}
this.value2 = newValue;
}
/**
* The fourth component of this vector
*/
public get [3](): number {
return this.value3;
}
public set [3](newValue: number) {
if (!this.updateFlag && this.value3 !== newValue) {
this.updateFlag = true;
}
this.value3 = newValue;
}
/**
* X component of the vector
*/
public get x(): number {
return this.value0;
}
public set x(newValue: number) {
this[0] = newValue;
}
/**
* Y component of the vector
*/
public get y(): number {
return this.value1;
}
public set y(newValue: number) {
this[1] = newValue;
}
/**
* Z component of the vector
*/
public get z(): number {
return this.value2;
}
public set z(newValue: number) {
this[2] = newValue;
}
/**
* W component of the vector
*/
public get w(): number {
return this.value3;
}
public set w(newValue: number) {
this[3] = newValue;
}
}
export { Vector4D };

View File

@ -0,0 +1,7 @@
export * from "./command/Command";
export * from "./command/CommandSet";
export * from "./command/CommandType";
export * from "./command/RenderCommand";
export * from "./command/ClearCommand";
export * from "./resource/Resource";
export * from "./resource/ResourceType";

View File

@ -0,0 +1,9 @@
import type { Command } from "./Command";
import type { CommandType } from "./CommandType";
interface ClearCommand extends Command {
type: CommandType.Clear
}
export type { ClearCommand };

View File

@ -0,0 +1,16 @@
import type { CommandTypeSet } from "./CommandType";
interface Command {
/**
* Define the type of command.
*/
type: CommandTypeSet;
/**
* Unique identification of the command for feedback.
*/
id?: string | number;
}
export type { Command };

View File

@ -0,0 +1,6 @@
import type { RenderCommand } from "./RenderCommand";
import type { ClearCommand } from "./ClearCommand";
type CommandSet = RenderCommand | ClearCommand;
export type { CommandSet };

View File

@ -0,0 +1,15 @@
namespace CommandType {
export type Render = "RENDER" | 100_001;
export type Resource = "RESOURCE" | 100_002;
export type Clear = "CLEAR" | 100_003;
export type Execute = "EXECUTE" | 100_004;
}
type CommandTypeSet = CommandType.Render | CommandType.Resource | CommandType.Clear | CommandType.Execute;
export type { CommandType, CommandTypeSet };

View File

@ -0,0 +1,12 @@
import type { Command } from "./Command";
import type { CommandType } from "./CommandType";
/**
* Rendering command are used to execute gl programs.
*/
interface RenderCommand extends Command {
type: CommandType.Render
}
export type { RenderCommand };

View File

@ -0,0 +1,8 @@
import type { CommandSet } from "../command/CommandSet"
interface Renderer {
executeCommand: (commands: CommandSet[] | CommandSet) => void;
}
export type { Renderer };

View File

@ -0,0 +1,10 @@
import type { ResourceSet } from "./ResourceType";
interface Resource {
type: ResourceSet;
id: string | number;
}
export type { Resource };

View File

@ -0,0 +1,9 @@
namespace ResourceType {
export type Shader = "SHADER" | 100_001;
}
type ResourceSet = ResourceType.Shader;
export type { ResourceType, ResourceSet };

View File

@ -0,0 +1,2 @@
import type * as VRenderer from "virtual-renderer";

16
package.json Normal file
View File

@ -0,0 +1,16 @@
{
"private": "true",
"name": "ray-lab",
"version": "1.0.0",
"description": "WebGL rendering engine based on native TypeScript.",
"scripts": {
"hmr-engine": "webpack serve --config ./webpack/Config.js --mode development --env entry=freeTest"
},
"keywords": [
"ray",
"ray-lab",
"3d",
"gl"
],
"author": "MrKBear"
}

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ray Lay Renderer Debugger</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/source/main.ts"></script>
</body>
</html>

View File

@ -0,0 +1,25 @@
{
"private": "true",
"name": "@ray-lab/renderer-debugger",
"version": "1.0.0",
"description": "",
"scripts": {
"dev": "vite"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@ray-lab/renderer-virtual": "workspace:*",
"@ray-lab/renderer-webgl": "workspace:*",
"vue": "^3.2.45"
},
"devDependencies": {
"@types/node": "^18.11.18",
"@vitejs/plugin-vue": "^4.0.0",
"@vue/tsconfig": "^0.1.3",
"typescript": "^4.9.4",
"vite": "^4.0.4",
"vite-plugin-vue-setup-extend": "^0.4.0"
}
}

View File

@ -0,0 +1,40 @@
<template>
<div ref="contentRef" class="content"></div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from "vue";
import { WebGLRenderer } from "@ray-lab/renderer-webgl";
const contentRef = ref<HTMLDivElement>();
const canvasEle = document.createElement("canvas");
onMounted(() => {
const renderer = new WebGLRenderer({
canvas: canvasEle,
container: contentRef.value,
autoResize: true,
width: 800,
height: 600
});
if (contentRef.value) {
contentRef.value.appendChild(canvasEle);
}
console.log(renderer);
})
</script>
<style>
html, body {
margin: 0;
}
div.content {
position: absolute;
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,5 @@
import { createApp } from "vue";
import AppVue from "./App.vue";
const oneMapApp = createApp(AppVue);
oneMapApp.mount("#app");

View File

@ -0,0 +1,28 @@
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"include": [
"./source/**/*",
"./source/**/*.vue"
],
"exclude": [
"node_modules",
"build"
],
"compilerOptions": {
"strict": true,
"alwaysStrict": true,
"baseUrl": "./",
"module": "ESNext",
"moduleResolution": "Node",
"useDefineForClassFields": true,
},
"references": [
{
"path": "./tsconfig.vite.json"
}
]
}

View File

@ -0,0 +1,8 @@
{
"extends": "@vue/tsconfig/tsconfig.node.json",
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*"],
"compilerOptions": {
"composite": true,
"types": ["node"]
}
}

View File

@ -0,0 +1,20 @@
import { defineConfig, type UserConfig, type ConfigEnv } from "vite";
import { default as vuePlugin } from "@vitejs/plugin-vue";
import { default as VueSetupExtend } from 'vite-plugin-vue-setup-extend';
import { resolve } from "path";
const projectPath = resolve(__dirname, "./");
const buildPath = resolve(projectPath, "./build");
async function viteConfig({ command, mode }: ConfigEnv): Promise<UserConfig> {
return {
root: projectPath,
build: {
outDir: buildPath,
},
plugins: [vuePlugin(), VueSetupExtend()]
}
}
export default defineConfig(viteConfig);

View File

@ -0,0 +1,20 @@
{
"name": "@ray-lab/renderer-virtual",
"version": "1.0.0",
"description": "Renderer Common Interface.",
"scripts": {
"build": "rollup -c rollup.config.js"
},
"type": "module",
"types": "./build/virtual-renderer.d.ts",
"keywords": [
"renderer-virtual",
"renderer"
],
"author": "MrKBear",
"devDependencies": {
"rollup": "^3.9.1",
"rollup-plugin-ts": "^3.0.2",
"typescript": "^4.9.4"
}
}

View File

@ -0,0 +1,20 @@
import tsPlugin from "rollup-plugin-ts";
/**
* @type {import("rollup").RollupOptions}
*/
const rollupConfig = {
input: "./source/virtual-renderer.ts",
output: [
{
file: "./build/virtual-renderer.d.ts",
format: "esm"
}
],
plugins: [tsPlugin()],
};
export default rollupConfig;

View File

@ -0,0 +1,9 @@
import type { Command } from "./Command";
import type { CommandType } from "./CommandType";
interface ClearCommand extends Command {
type: CommandType.Clear
}
export type { ClearCommand };

View File

@ -0,0 +1,16 @@
import type { CommandTypeSet } from "./CommandType";
interface Command {
/**
* Define the type of command.
*/
type: CommandTypeSet;
/**
* Unique identification of the command for feedback.
*/
id?: string | number;
}
export type { Command };

View File

@ -0,0 +1,6 @@
import type { RenderCommand } from "./RenderCommand";
import type { ClearCommand } from "./ClearCommand";
type CommandSet = RenderCommand | ClearCommand;
export type { CommandSet };

View File

@ -0,0 +1,15 @@
namespace CommandType {
export type Render = "RENDER" | 100_001;
export type Resource = "RESOURCE" | 100_002;
export type Clear = "CLEAR" | 100_003;
export type Execute = "EXECUTE" | 100_004;
}
type CommandTypeSet = CommandType.Render | CommandType.Resource | CommandType.Clear | CommandType.Execute;
export type { CommandType, CommandTypeSet };

View File

@ -0,0 +1,12 @@
import type { Command } from "./Command";
import type { CommandType } from "./CommandType";
/**
* Rendering command are used to execute gl programs.
*/
interface RenderCommand extends Command {
type: CommandType.Render
}
export type { RenderCommand };

View File

@ -0,0 +1,8 @@
import type { CommandSet } from "command/CommandSet"
interface Renderer {
executeCommand: (commands: CommandSet[] | CommandSet) => void;
}
export type { Renderer };

View File

@ -0,0 +1,18 @@
type ResourceNameType = string | number;
type ResourceIdType = string | number | symbol;
interface Resource {
/**
* Unique identification of resource type.
*/
type: ResourceNameType;
/**
* Unique number of the resource instance.
*/
id: ResourceIdType;
}
export type { Resource, ResourceNameType, ResourceIdType };

View File

@ -0,0 +1,10 @@
import type { ShaderResource } from "./ShaderResource";
namespace ResourceName {
export type Shader = ShaderResource["type"];
}
type ResourceSet = ShaderResource;
type ResourceNameSet = ResourceName.Shader;
export type { ResourceName, ResourceNameSet, ResourceSet };

View File

@ -0,0 +1,8 @@
import type { Resource } from "./Resource";
interface ShaderResource extends Resource {
type: "SHADER" | 100_001;
}
export type { ShaderResource };

View File

@ -0,0 +1,8 @@
export * from "command/Command";
export * from "command/CommandSet";
export * from "command/CommandType";
export * from "command/RenderCommand";
export * from "command/ClearCommand";
export * from "resource/Resource";
export * from "resource/ResourceSet";
export * from "resource/ShaderResource";

View File

@ -0,0 +1,24 @@
{
"compilerOptions": {
"strict": true,
"declaration": true,
"declarationDir": "build",
"baseUrl": "./",
"lib": [
"ESNext"
],
"paths": {
"command/*": ["./source/command/*"],
"common/*": ["./source/common/*"],
"resource/*": ["./source/resource/*"],
"renderer/*": ["./source/renderer/*"]
}
},
"include": [
"./source/**/*"
],
"exclude": [
"node_modules",
"build"
]
}

View File

@ -0,0 +1,23 @@
{
"name": "@ray-lab/renderer-webgl",
"version": "1.0.0",
"description": "",
"main": "./build/webgl-renderer.js",
"scripts": {
"build": "rollup -c rollup.config.js"
},
"type": "module",
"types": "./build/webgl-renderer.d.ts",
"keywords": [],
"author": "MrKBear",
"license": "ISC",
"dependencies": {
"@juggle/resize-observer": "^3.4.0",
"@ray-lab/renderer-virtual": "workspace:*"
},
"devDependencies": {
"rollup": "^3.9.1",
"rollup-plugin-ts": "^3.0.2",
"typescript": "^4.9.4"
}
}

View File

@ -0,0 +1,20 @@
import tsPlugin from "rollup-plugin-ts";
/**
* @type {import("rollup").RollupOptions}
*/
const rollupConfig = {
input: "./source/webgl-renderer.ts",
output: [
{
file: "./build/webgl-renderer.js",
format: "esm"
}
],
plugins: [tsPlugin()],
};
export default rollupConfig;

View File

@ -0,0 +1,6 @@
class CommandHandler {
}
export { CommandHandler };

View File

@ -0,0 +1,10 @@
import type { CommandHandler } from "./CommandHandler";
class CommandInterpreter {
public addCommandHandler(commandHandler: CommandHandler) {
}
public removeCommandHandler() {}
}

View File

@ -0,0 +1,105 @@
/**
* Allowed event name.
*/
type EventName = string | number | symbol;
type EventHandler<Value> = (value?: Value) => any;
/**
* An internally used event emitter model.
*/
class EventEmitter<EventMap extends Record<EventName, any> = {}> {
private eventMap = new Map<keyof EventMap, Set<Function>>;
/**
* Add a listener for a given event.
* @param event - event name.
* @param handler - event handler.
*/
public addListener<T extends keyof EventMap>(event: T, handler: EventHandler<EventMap[T]>): void {
let handlerSet = this.eventMap.get(event);
if (!handlerSet) {
handlerSet = new Set();
this.eventMap.set(event, handlerSet);
}
handlerSet.add(handler);
}
/**
* Alias of `EventEmitter.addListener`.
*/
public declare on: <T extends keyof EventMap>(event: T, handler: EventHandler<EventMap[T]>) => void;
/**
* Remove the listeners of a given event.
* @param event - event name.
* @param handler - event handler.
*/
public removeListener<T extends keyof EventMap>(event: T, handler: EventHandler<EventMap[T]>) {
let handlerSet = this.eventMap.get(event);
if (handlerSet) {
handlerSet.delete(handler);
}
}
/**
* Alias of `EventEmitter.removeListener`.
*/
public declare off: <T extends keyof EventMap>(event: T, handler: EventHandler<EventMap[T]>) => void;
/**
* Remove all listeners of a given event.
* @param event - event name.
* @param handler - event handler.
*/
public removeAllListener<T extends keyof EventMap>(event: T) {
this.eventMap.set(event, new Set());
}
/**
* Alias of `EventEmitter.removeAllListener`.
*/
public declare offAll: <T extends keyof EventMap>(event: T) => void;
/**
* emit event.
*/
public emit<T extends keyof EventMap>(...param: EventMap[T] extends void ? [T] : [T, EventMap[T]]) {
let handlerSet = this.eventMap.get(param[0]);
if (handlerSet) {
for (const handler of handlerSet) {
handler(param[1]);
}
}
}
/**
* Remove all listeners.
*/
public clearAllListener() {
this.eventMap.clear();
this.eventMap = new Map();
}
/**
* Get the number of listeners for a given event.
* @param event - event name.
*/
public listenerCount<T extends keyof EventMap>(event: T): number {
let handlerSet = this.eventMap.get(event);
if (handlerSet) {
return handlerSet.size;
}
else {
return 0;
}
}
}
// Register alias.
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.offAll = EventEmitter.prototype.removeAllListener;
export { EventEmitter };

View File

@ -0,0 +1,63 @@
import { Resource, ResourceNameType, ResourceIdType } from "@ray-lab/renderer-virtual";
/**
* Resource processing tools.
* Whenever a new resource setting is received,
* an instance of this class will be instantiated to manage the received resource.
* @typeParam ResourceOption - Resource option type.
*/
abstract class ResourceHandler<ResourceOption extends Resource = Resource> {
/**
* Resource type enumeration.
*/
public static resourceType: ResourceNameType;
public static resourceTypeAlias: ResourceNameType;
/**
* Original resource option.
*/
public resourceOption: ResourceOption;
/**
* Resource unique number.
*/
public resourceId: ResourceIdType;
/**
* @param resourceOption - Resource option.
*/
public constructor(resourceOption: ResourceOption) {
this.resourceOption = resourceOption;
this.resourceId = resourceOption.id ?? Symbol(resourceOption.type);
}
/**
* Resource initialization lifecycle.
* It will be called once after `WebGLState` is ready.
*/
public abstract setup(): any;
/**
* Marks whether the instance is destroyed.
*/
public isDestroyed: boolean = false;
/**
* Resource destruction lifecycle.
* Will be called when the resource is destroyed.
*/
public abstract destroy(): any;
/**
* Resource Settings Update Lifecycle.
* Called when the resource settings will to be updated.
* At this time, you can access the old settings through `this.resourceOption`.
*
* Note:
* You don't need to execute ```this.resourceOption = newResourceOption``` manually,
* The assignment will be done after this function returns.
* @param newResourceOption - New resource option.
*/
public abstract update(newResourceOption: ResourceOption): any;
}

View File

@ -0,0 +1,8 @@
/**
* Used to manage and process all GL resources.
* Rely on adding `ResourceHandler` to extend functions.
*/
class ResourcePool {
}

View File

@ -0,0 +1,22 @@
import { WebGLCanvas } from "state/WebGLCanvas";
import { WebGLState } from "state/WebGLState";
import type { WebGLCanvasOption } from "state/WebGLCanvas";
type WebGLRendererOption = WebGLCanvasOption;
class WebGLRenderer {
public canvas: WebGLCanvas;
public state: WebGLState;
public constructor(option: WebGLRendererOption) {
this.canvas = new WebGLCanvas(option);
this.state = new WebGLState();
this.state.bindCanvas(this.canvas);
}
}
export { WebGLRenderer };

View File

@ -0,0 +1,335 @@
import { ResizeObserver as ResizeObserverPolyfill } from '@juggle/resize-observer';
import { EventEmitter } from "kernel/EventEmitter";
const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
interface WebGLCanvasOption {
/**
* Canvas element for outputting renderer images.
* If a string is passed in:
* Here will try `document.getElementById` and then `document.querySelector`
* until a valid canvas element is found.
*/
canvas?: HTMLCanvasElement | OffscreenCanvas | string;
/**
* Initialize with WebGL context.
*/
context?: WebGLRenderingContext | WebGL2RenderingContext;
/**
* Parent node of canvas.
*/
container?: HTMLElement | string;
/**
* Automatically adjust width and height to parent node width and height.
*/
autoResize?: boolean;
/**
* Width of Canvas.
* It will become invalid when autoResize is set.
*/
width?: number;
/**
* Height of Canvas.
* It will become invalid when autoResize is set.
*/
height?: number;
/**
* Whether to use offline canvas.
*/
isOffScreen?: boolean;
/**
* WebGL context attributes.
*/
contextAttributes?: WebGLContextAttributes;
}
type WebGLCanvasEventMap = {
/**
* Emit When the canvas size changes.
*/
"resize": void;
};
class WebGLCanvas extends EventEmitter<WebGLCanvasEventMap> {
public readonly element: HTMLCanvasElement | OffscreenCanvas;
public readonly context: WebGLRenderingContext | WebGL2RenderingContext;
public readonly glVersion: 0 | 1 | 2;
public readonly isOffScreen: boolean;
public constructor(userOption?: WebGLCanvasOption) {
super();
const option: WebGLCanvasOption = userOption ?? {};
let targetCanvas: HTMLCanvasElement | OffscreenCanvas | undefined = void 0;
let targetContext: WebGLRenderingContext | WebGL2RenderingContext | undefined = void 0;
let targetGLVersion: 0 | 1 | 2 = 0;
let targetIsOffScreen: boolean = false;
if (option.canvas instanceof HTMLCanvasElement || option.canvas instanceof OffscreenCanvas) {
targetCanvas = option.canvas;
}
else if (typeof option.canvas === "string") {
let findTarget: HTMLElement | null = null;
findTarget = document.getElementById(option.canvas);
if (findTarget instanceof HTMLCanvasElement) {
targetCanvas = findTarget;
}
else {
findTarget = document.querySelector(option.canvas);
if (findTarget instanceof HTMLCanvasElement) {
targetCanvas = findTarget;
}
else {
console.warn(
`[ray-lab Renderer] Unable to search any valid canvas through "${option.canvas}". \r\n` +
"Created internal canvas instead..."
);
}
}
}
if (option.context) {
if (targetCanvas && targetCanvas !== option.context.canvas) {
console.warn(
"[ray-lab Renderer] The `canvas` element does not match the `context.canvas`: \r\n" +
"The `canvas` option will be ignored. \r\n" +
"Please do not use `canvas` and `context` at the same time!"
);
}
targetCanvas = option.context.canvas;
targetContext = option.context;
}
if (targetCanvas) {
if (targetCanvas instanceof HTMLCanvasElement) {
if (option.isOffScreen) {
if (OffscreenCanvas) {
targetCanvas = targetCanvas.transferControlToOffscreen();
targetIsOffScreen = true;
}
else {
targetIsOffScreen = false;
console.warn(
"[ray-lab Renderer] The target environment does not support OffscreenCanvas \r\n" +
"`isOffScreen` is ignored!"
);
}
}
else {
targetIsOffScreen = false;
}
}
else if (targetCanvas instanceof OffscreenCanvas) {
targetIsOffScreen = true;
}
}
else {
if (option.isOffScreen) {
if (OffscreenCanvas) {
targetIsOffScreen = true;
targetCanvas = new OffscreenCanvas(option.width ?? 300, option.height ?? 150);
}
else {
targetIsOffScreen = false;
targetCanvas = document.createElement("canvas");
console.warn(
"[ray-lab Renderer] The target environment does not support OffscreenCanvas \r\n" +
"`isOffScreen` is ignored!"
);
}
}
else {
targetIsOffScreen = false;
targetCanvas = document.createElement("canvas");
}
}
if (targetContext) {
if (targetCanvas instanceof WebGL2RenderingContext) {
targetGLVersion = 2;
}
else if (targetCanvas instanceof WebGLRenderingContext) {
targetGLVersion = 1;
}
}
else {
let getContext: OffscreenRenderingContext | RenderingContext | null;
getContext = targetCanvas.getContext("webgl2", option.contextAttributes);
if (!getContext) {
getContext = targetCanvas.getContext("webgl", option.contextAttributes);
}
if (WebGL2RenderingContext && (getContext instanceof WebGL2RenderingContext)) {
targetContext = getContext;
targetGLVersion = 2;
}
else if (getContext instanceof WebGLRenderingContext) {
targetContext = getContext;
targetGLVersion = 1;
}
else {
throw new Error("[ray-lab Renderer] The target environment does not support WebGL :(");
}
}
this.element = targetCanvas;
this.context = targetContext;
this.glVersion = targetGLVersion;
this.isOffScreen = targetIsOffScreen;
if (option.autoResize) {
this.enableAutoResize(option.container);
}
else {
this.resize(option.width, option.height);
}
}
/**
* Change the canvas size.
* @param width - canvas width.
* @param height - canvas height.
*/
public resize(width?: number, height?: number) {
let hasResized = false;
if (width !== void 0) {
this.element.width = width;
hasResized = true;
}
if (height !== void 0) {
this.element.height = height;
hasResized = true;
}
if (hasResized) {
this.emit("resize");
}
}
private resizeObserver: ResizeObserver | undefined;
/**
* enable auto resize.
* @param container - Parent node of canvas.
*/
public enableAutoResize(container?: HTMLElement | string) {
let targetcontainer: HTMLElement | null = null;
if (container instanceof HTMLElement) {
targetcontainer = container;
}
else if (typeof container === "string") {
targetcontainer = document.getElementById(container);
if (targetcontainer === null) {
targetcontainer = document.querySelector(container);
if (targetcontainer === null) {
console.warn(
`[ray-lab Renderer] Unable to search any valid container through "${container}".`
);
}
}
}
if (targetcontainer === null && this.element instanceof HTMLCanvasElement) {
targetcontainer = this.element.parentElement;
}
if (targetcontainer === null) {
console.warn(
`[ray-lab Renderer] Unable to enable auto resize. \r\n` +
`Because a suitable container could not be found.`
);
}
else {
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
if (entry.contentRect) {
this.resize(entry.contentRect.width, entry.contentRect.height);
}
}
});
if (this.resizeObserver) {
this.resizeObserver.disconnect();
}
this.resizeObserver = resizeObserver;
if (this.element instanceof HTMLElement) {
this.element.style.width = "100%";
this.element.style.height = "100%";
this.element.style.boxSizing = "border-box";
this.element.style.display = "block";
}
resizeObserver.observe(targetcontainer);
this.resize(targetcontainer.offsetWidth, targetcontainer.offsetHeight);
}
}
/**
* disable auto resize.
*/
public disableAutoResize() {
if (this.resizeObserver) {
this.resizeObserver.disconnect();
}
this.resizeObserver = void 0;
}
}
export { WebGLCanvas };
export type { WebGLCanvasOption };

View File

@ -0,0 +1,37 @@
import type { WebGLCanvas } from "./WebGLCanvas";
import { WebGLStateAbstract } from "./WebGLStateAbstract";
class WebGLState extends WebGLStateAbstract {
private statePool: Array<WebGLStateAbstract> = [];
private registerState(state: WebGLStateAbstract) {
this.statePool.push(state);
}
public override contextWillBind(newcanvas: WebGLCanvas) {
for (const state of this.statePool) {
state.bindCanvas(newcanvas);
}
}
public override contextLost() {
for (const state of this.statePool) {
state.contextLost();
}
}
public override resetState() {
for (const state of this.statePool) {
state.resetState();
}
}
public override destroy() {
for (const state of this.statePool) {
state.destroy();
}
}
}
export { WebGLState };

View File

@ -0,0 +1,56 @@
import type { WebGLCanvas } from "./WebGLCanvas";
/**
* Used for management, caching, encapsulation, WebGL context.
*/
abstract class WebGLStateAbstract {
private _canvas: WebGLCanvas | undefined;
/**
* binded canvas.
*/
public get canvas(): WebGLCanvas {
if (this._canvas) {
return this._canvas;
}
else {
throw new Error(
"[ray-lab WebGLStateBasic] Please get canvas instance after context binding."
);
}
};
/**
* Bind new WebGLCanvas.
*/
public bindCanvas(canvas: WebGLCanvas) {
this.contextWillBind(canvas);
this._canvas = canvas;
};
/**
* Life cycle hook function.
* Triggered when the context is rebound.
* @param newcanvas - New canvas object to be bound.
*/
public abstract contextWillBind(newcanvas: WebGLCanvas): any;
/**
* Life cycle hook function.
* Triggered when the context is lost.
*/
public abstract contextLost(): any;
/**
* Reset all states.
*/
public abstract resetState(): any;
/**
* Triggered when destroyed.
*/
public abstract destroy(): any;
}
export { WebGLStateAbstract };

View File

@ -0,0 +1,3 @@
export * from "state/WebGLCanvas";
export * from "kernel/EventEmitter";
export * from "renderer/WebGLRenderer";

View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"strict": true,
"baseUrl": "./",
"module": "ESNext",
"moduleResolution": "Node",
"target": "ESNext",
"declaration": true,
"lib": [
"DOM",
"DOM.Iterable",
"ESNext"
],
"paths": {
"kernel/*": ["./source/kernel/*"],
"renderer/*": ["./source/renderer/*"],
"state/*": ["./source/state/*"]
}
}
}

792
pnpm-lock.yaml generated Normal file
View File

@ -0,0 +1,792 @@
lockfileVersion: 5.4
importers:
.:
specifiers: {}
packages/renderer-debugger:
specifiers:
'@ray-lab/renderer-virtual': workspace:*
'@ray-lab/renderer-webgl': workspace:*
'@types/node': ^18.11.18
'@vitejs/plugin-vue': ^4.0.0
'@vue/tsconfig': ^0.1.3
typescript: ^4.9.4
vite: ^4.0.4
vite-plugin-vue-setup-extend: ^0.4.0
vue: ^3.2.45
dependencies:
'@ray-lab/renderer-virtual': link:../renderer-virtual
'@ray-lab/renderer-webgl': link:../renderer-webgl
vue: 3.2.45
devDependencies:
'@types/node': 18.11.18
'@vitejs/plugin-vue': 4.0.0_vite@4.0.4+vue@3.2.45
'@vue/tsconfig': 0.1.3_@types+node@18.11.18
typescript: 4.9.4
vite: 4.0.4_@types+node@18.11.18
vite-plugin-vue-setup-extend: 0.4.0_vite@4.0.4
packages/renderer-virtual:
specifiers:
rollup: ^3.9.1
rollup-plugin-ts: ^3.0.2
typescript: ^4.9.4
devDependencies:
rollup: 3.9.1
rollup-plugin-ts: 3.0.2_esmavzhadgk2idmxtiodxm33ma
typescript: 4.9.4
packages/renderer-webgl:
specifiers:
'@juggle/resize-observer': ^3.4.0
'@ray-lab/renderer-virtual': workspace:*
rollup: ^3.9.1
rollup-plugin-ts: ^3.0.2
typescript: ^4.9.4
dependencies:
'@juggle/resize-observer': 3.4.0
'@ray-lab/renderer-virtual': link:../renderer-virtual
devDependencies:
rollup: 3.9.1
rollup-plugin-ts: 3.0.2_esmavzhadgk2idmxtiodxm33ma
typescript: 4.9.4
packages:
/@babel/helper-string-parser/7.19.4:
resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==}
engines: {node: '>=6.9.0'}
/@babel/helper-validator-identifier/7.19.1:
resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
engines: {node: '>=6.9.0'}
/@babel/parser/7.20.7:
resolution: {integrity: sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
'@babel/types': 7.20.7
/@babel/types/7.20.7:
resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-string-parser': 7.19.4
'@babel/helper-validator-identifier': 7.19.1
to-fast-properties: 2.0.0
/@esbuild/android-arm/0.16.14:
resolution: {integrity: sha512-u0rITLxFIeYAvtJXBQNhNuV4YZe+MD1YvIWT7Nicj8hZAtRVZk2PgNH6KclcKDVHz1ChLKXRfX7d7tkbQBUfrg==}
engines: {node: '>=12'}
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-arm64/0.16.14:
resolution: {integrity: sha512-hTqB6Iq13pW4xaydeqQrs8vPntUnMjbkq+PgGiBMi69eYk74naG2ftHWqKnxn874kNrt5Or3rQ0PJutx2doJuQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-x64/0.16.14:
resolution: {integrity: sha512-jir51K4J0K5Rt0KOcippjSNdOl7akKDVz5I6yrqdk4/m9y+rldGptQUF7qU4YpX8U61LtR+w2Tu2Ph+K/UaJOw==}
engines: {node: '>=12'}
cpu: [x64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-arm64/0.16.14:
resolution: {integrity: sha512-vrlaP81IuwPaw1fyX8fHCmivP3Gr73ojVEZy+oWJLAiZVcG8o8Phwun/XDnYIFUHxIoUnMFEpg9o38MIvlw8zw==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-x64/0.16.14:
resolution: {integrity: sha512-KV1E01eC2hGYA2qzFDRCK4wdZCRUvMwCNcobgpiiOzp5QXpJBqFPdxI69j8vvzuU7oxFXDgANwEkXvpeQqyOyg==}
engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-arm64/0.16.14:
resolution: {integrity: sha512-xRM1RQsazSvL42BNa5XC7ytD4ZDp0ZyJcH7aB0SlYUcHexJUKiDNKR7dlRVlpt6W0DvoRPU2nWK/9/QWS4u2fw==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-x64/0.16.14:
resolution: {integrity: sha512-7ALTAn6YRRf1O6fw9jmn0rWmOx3XfwDo7njGtjy1LXhDGUjTY/vohEPM3ii5MQ411vJv1r498EEx2aBQTJcrEw==}
engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm/0.16.14:
resolution: {integrity: sha512-X6xULug66ulrr4IzrW7qq+eq9n4MtEyagdWvj4o4cmWr+JXOT47atjpDF9j5M2zHY0UQBmqnHhwl+tXpkpIb2w==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm64/0.16.14:
resolution: {integrity: sha512-TLh2OcbBUQcMYRH4GbiDkDZfZ4t1A3GgmeXY27dHSI6xrU7IkO00MGBiJySmEV6sH3Wa6pAN6UtaVL0DwkGW4Q==}
engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ia32/0.16.14:
resolution: {integrity: sha512-oBZkcZ56UZDFCAfE3Fd/Jgy10EoS7Td77NzNGenM+HSY8BkdQAcI9VF9qgwdOLZ+tuftWD7UqZ26SAhtvA3XhA==}
engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-loong64/0.16.14:
resolution: {integrity: sha512-udz/aEHTcuHP+xdWOJmZ5C9RQXHfZd/EhCnTi1Hfay37zH3lBxn/fNs85LA9HlsniFw2zccgcbrrTMKk7Cn1Qg==}
engines: {node: '>=12'}
cpu: [loong64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-mips64el/0.16.14:
resolution: {integrity: sha512-kJ2iEnikUOdC1SiTGbH0fJUgpZwa0ITDTvj9EHf9lm3I0hZ4Yugsb3M6XSl696jVxrEocLe519/8CbSpQWFSrg==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ppc64/0.16.14:
resolution: {integrity: sha512-kclKxvZvX5YhykwlJ/K9ljiY4THe5vXubXpWmr7q3Zu3WxKnUe1VOZmhkEZlqtnJx31GHPEV4SIG95IqTdfgfg==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-riscv64/0.16.14:
resolution: {integrity: sha512-fdwP9Dc+Kx/cZwp9T9kNqjAE/PQjfrxbio4rZ3XnC3cVvZBjuxpkiyu/tuCwt6SbAK5th6AYNjFdEV9kGC020A==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-s390x/0.16.14:
resolution: {integrity: sha512-++fw3P4fQk9nqvdzbANRqimKspL8pDCnSpXomyhV7V/ISha/BZIYvZwLBWVKp9CVWKwWPJ4ktsezuLIvlJRHqA==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-x64/0.16.14:
resolution: {integrity: sha512-TomtswAuzBf2NnddlrS4W01Tv85RM9YtATB3OugY6On0PLM4Ksz5qvQKVAjtzPKoLgL1FiZtfc8mkZc4IgoMEA==}
engines: {node: '>=12'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/netbsd-x64/0.16.14:
resolution: {integrity: sha512-U06pfx8P5CqyoPNfqIJmnf+5/r4mJ1S62G4zE6eOjS59naQcxi6GnscUCPH3b+hRG0qdKoGX49RAyiqW+M9aSw==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/openbsd-x64/0.16.14:
resolution: {integrity: sha512-/Jl8XVaWEZNu9rZw+n792GIBupQwHo6GDoapHSb/2xp/Ku28eK6QpR2O9cPBkzHH4OOoMH0LB6zg/qczJ5TTGg==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/sunos-x64/0.16.14:
resolution: {integrity: sha512-2iI7D34uTbDn/TaSiUbEHz+fUa8KbN90vX5yYqo12QGpu6T8Jl+kxODsWuMCwoTVlqUpwfPV22nBbFPME9OPtw==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-arm64/0.16.14:
resolution: {integrity: sha512-SjlM7AHmQVTiGBJE/nqauY1aDh80UBsXZ94g4g60CDkrDMseatiqALVcIuElg4ZSYzJs8hsg5W6zS2zLpZTVgg==}
engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-ia32/0.16.14:
resolution: {integrity: sha512-z06t5zqk8ak0Xom5HG81z2iOQ1hNWYsFQp3sczVLVx+dctWdgl80tNRyTbwjaFfui2vFO12dfE3trCTvA+HO4g==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-x64/0.16.14:
resolution: {integrity: sha512-ED1UpWcM6lAbalbbQ9TrGqJh4Y9TaASUvu8bI/0mgJcxhSByJ6rbpgqRhxYMaQ682WfA71nxUreaTO7L275zrw==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@juggle/resize-observer/3.4.0:
resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
dev: false
/@mdn/browser-compat-data/4.2.1:
resolution: {integrity: sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==}
dev: true
/@rollup/pluginutils/4.2.1:
resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
engines: {node: '>= 8.0.0'}
dependencies:
estree-walker: 2.0.2
picomatch: 2.3.1
dev: true
/@types/node/17.0.45:
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
dev: true
/@types/node/18.11.18:
resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==}
dev: true
/@types/object-path/0.11.1:
resolution: {integrity: sha512-219LSCO9HPcoXcRTC6DbCs0FRhZgBnEMzf16RRqkT40WbkKx3mOeQuz3e2XqbfhOz/AHfbru0kzB1n1RCAsIIg==}
dev: true
/@types/semver/7.3.13:
resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
dev: true
/@types/ua-parser-js/0.7.36:
resolution: {integrity: sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==}
dev: true
/@vitejs/plugin-vue/4.0.0_vite@4.0.4+vue@3.2.45:
resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
vite: ^4.0.0
vue: ^3.2.25
dependencies:
vite: 4.0.4_@types+node@18.11.18
vue: 3.2.45
dev: true
/@vue/compiler-core/3.2.45:
resolution: {integrity: sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==}
dependencies:
'@babel/parser': 7.20.7
'@vue/shared': 3.2.45
estree-walker: 2.0.2
source-map: 0.6.1
/@vue/compiler-dom/3.2.45:
resolution: {integrity: sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==}
dependencies:
'@vue/compiler-core': 3.2.45
'@vue/shared': 3.2.45
/@vue/compiler-sfc/3.2.45:
resolution: {integrity: sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==}
dependencies:
'@babel/parser': 7.20.7
'@vue/compiler-core': 3.2.45
'@vue/compiler-dom': 3.2.45
'@vue/compiler-ssr': 3.2.45
'@vue/reactivity-transform': 3.2.45
'@vue/shared': 3.2.45
estree-walker: 2.0.2
magic-string: 0.25.9
postcss: 8.4.20
source-map: 0.6.1
/@vue/compiler-ssr/3.2.45:
resolution: {integrity: sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==}
dependencies:
'@vue/compiler-dom': 3.2.45
'@vue/shared': 3.2.45
/@vue/reactivity-transform/3.2.45:
resolution: {integrity: sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==}
dependencies:
'@babel/parser': 7.20.7
'@vue/compiler-core': 3.2.45
'@vue/shared': 3.2.45
estree-walker: 2.0.2
magic-string: 0.25.9
/@vue/reactivity/3.2.45:
resolution: {integrity: sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==}
dependencies:
'@vue/shared': 3.2.45
/@vue/runtime-core/3.2.45:
resolution: {integrity: sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==}
dependencies:
'@vue/reactivity': 3.2.45
'@vue/shared': 3.2.45
/@vue/runtime-dom/3.2.45:
resolution: {integrity: sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==}
dependencies:
'@vue/runtime-core': 3.2.45
'@vue/shared': 3.2.45
csstype: 2.6.21
/@vue/server-renderer/3.2.45_vue@3.2.45:
resolution: {integrity: sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==}
peerDependencies:
vue: 3.2.45
dependencies:
'@vue/compiler-ssr': 3.2.45
'@vue/shared': 3.2.45
vue: 3.2.45
/@vue/shared/3.2.45:
resolution: {integrity: sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==}
/@vue/tsconfig/0.1.3_@types+node@18.11.18:
resolution: {integrity: sha512-kQVsh8yyWPvHpb8gIc9l/HIDiiVUy1amynLNpCy8p+FoCiZXCo6fQos5/097MmnNZc9AtseDsCrfkhqCrJ8Olg==}
peerDependencies:
'@types/node': '*'
peerDependenciesMeta:
'@types/node':
optional: true
dependencies:
'@types/node': 18.11.18
dev: true
/@wessberg/stringutil/1.0.19:
resolution: {integrity: sha512-9AZHVXWlpN8Cn9k5BC/O0Dzb9E9xfEMXzYrNunwvkUTvuK7xgQPVRZpLo+jWCOZ5r8oBa8NIrHuPEu1hzbb6bg==}
engines: {node: '>=8.0.0'}
dev: true
/ansi-colors/4.1.3:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
dev: true
/browserslist-generator/1.0.66:
resolution: {integrity: sha512-aFDax4Qzh29DdyhHQBD2Yu2L5OvaDnvYFMbmpLrLwwaNK4H6dHEhC/Nxv93/+mfAA+a/t94ln0P2JZvHO6LZDA==}
engines: {node: '>=8.0.0'}
dependencies:
'@mdn/browser-compat-data': 4.2.1
'@types/object-path': 0.11.1
'@types/semver': 7.3.13
'@types/ua-parser-js': 0.7.36
browserslist: 4.20.2
caniuse-lite: 1.0.30001442
isbot: 3.4.5
object-path: 0.11.8
semver: 7.3.8
ua-parser-js: 1.0.32
dev: true
/browserslist/4.20.2:
resolution: {integrity: sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001442
electron-to-chromium: 1.4.284
escalade: 3.1.1
node-releases: 2.0.8
picocolors: 1.0.0
dev: true
/browserslist/4.21.4:
resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001442
electron-to-chromium: 1.4.284
node-releases: 2.0.8
update-browserslist-db: 1.0.10_browserslist@4.21.4
dev: true
/caniuse-lite/1.0.30001442:
resolution: {integrity: sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==}
dev: true
/compatfactory/1.0.1_typescript@4.9.4:
resolution: {integrity: sha512-hR9u0HSZTKDNNchPtMHg6myeNx0XO+av7UZIJPsi4rPALJBHi/W5Mbwi19hC/xm6y3JkYpxVYjTqnSGsU5X/iw==}
engines: {node: '>=14.9.0'}
peerDependencies:
typescript: '>=3.x || >= 4.x'
dependencies:
helpertypes: 0.0.18
typescript: 4.9.4
dev: true
/crosspath/2.0.0:
resolution: {integrity: sha512-ju88BYCQ2uvjO2bR+SsgLSTwTSctU+6Vp2ePbKPgSCZyy4MWZxYsT738DlKVRE5utUjobjPRm1MkTYKJxCmpTA==}
engines: {node: '>=14.9.0'}
dependencies:
'@types/node': 17.0.45
dev: true
/csstype/2.6.21:
resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==}
/electron-to-chromium/1.4.284:
resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==}
dev: true
/esbuild/0.16.14:
resolution: {integrity: sha512-6xAn3O6ZZyoxZAEkwfI9hw4cEqSr/o1ViJtnkvImVkblmUN65Md04o0S/7H1WNu1XGf1Cjij/on7VO4psIYjkw==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
optionalDependencies:
'@esbuild/android-arm': 0.16.14
'@esbuild/android-arm64': 0.16.14
'@esbuild/android-x64': 0.16.14
'@esbuild/darwin-arm64': 0.16.14
'@esbuild/darwin-x64': 0.16.14
'@esbuild/freebsd-arm64': 0.16.14
'@esbuild/freebsd-x64': 0.16.14
'@esbuild/linux-arm': 0.16.14
'@esbuild/linux-arm64': 0.16.14
'@esbuild/linux-ia32': 0.16.14
'@esbuild/linux-loong64': 0.16.14
'@esbuild/linux-mips64el': 0.16.14
'@esbuild/linux-ppc64': 0.16.14
'@esbuild/linux-riscv64': 0.16.14
'@esbuild/linux-s390x': 0.16.14
'@esbuild/linux-x64': 0.16.14
'@esbuild/netbsd-x64': 0.16.14
'@esbuild/openbsd-x64': 0.16.14
'@esbuild/sunos-x64': 0.16.14
'@esbuild/win32-arm64': 0.16.14
'@esbuild/win32-ia32': 0.16.14
'@esbuild/win32-x64': 0.16.14
dev: true
/escalade/3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
dev: true
/estree-walker/2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
/fsevents/2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
dev: true
optional: true
/function-bind/1.1.1:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
dev: true
/has/1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
dependencies:
function-bind: 1.1.1
dev: true
/helpertypes/0.0.18:
resolution: {integrity: sha512-XRhfbSEmR+poXUC5/8AbmYNJb2riOT6qPzjGJZr0S9YedHiaY+/tzPYzWMUclYMEdCYo/1l8PDYrQFCj02v97w==}
engines: {node: '>=10.0.0'}
dev: true
/is-core-module/2.11.0:
resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==}
dependencies:
has: 1.0.3
dev: true
/isbot/3.4.5:
resolution: {integrity: sha512-+KD6q1BBtw0iK9aGBGSfxJ31/ZgizKRjhm8ebgJUBMx0aeeQuIJ1I72beCoIrltIZGrSm4vmrxRxrG5n1aUTtw==}
engines: {node: '>=12'}
dev: true
/lru-cache/6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'}
dependencies:
yallist: 4.0.0
dev: true
/magic-string/0.25.9:
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
dependencies:
sourcemap-codec: 1.4.8
/magic-string/0.26.7:
resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==}
engines: {node: '>=12'}
dependencies:
sourcemap-codec: 1.4.8
dev: true
/nanoid/3.3.4:
resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
/node-releases/2.0.8:
resolution: {integrity: sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==}
dev: true
/object-path/0.11.8:
resolution: {integrity: sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==}
engines: {node: '>= 10.12.0'}
dev: true
/path-parse/1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true
/picocolors/1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
/picomatch/2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
dev: true
/postcss/8.4.20:
resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
nanoid: 3.3.4
picocolors: 1.0.0
source-map-js: 1.0.2
/resolve/1.22.1:
resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
hasBin: true
dependencies:
is-core-module: 2.11.0
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
dev: true
/rollup-plugin-ts/3.0.2_esmavzhadgk2idmxtiodxm33ma:
resolution: {integrity: sha512-67qi2QTHewhLyKDG6fX3jpohWpmUPPIT/xJ7rsYK46X6MqmoWy64Ti0y8ygPfLv8mXDCdRZUofM3mTxDfCswRA==}
engines: {node: '>=14.9.0', npm: '>=7.0.0', pnpm: '>=3.2.0', yarn: '>=1.13'}
peerDependencies:
'@babel/core': '>=6.x || >=7.x'
'@babel/plugin-transform-runtime': '>=6.x || >=7.x'
'@babel/preset-env': '>=6.x || >=7.x'
'@babel/preset-typescript': '>=6.x || >=7.x'
'@babel/runtime': '>=6.x || >=7.x'
'@swc/core': '>=1.x'
'@swc/helpers': '>=0.2'
rollup: '>=1.x || >=2.x'
typescript: '>=3.2.x || >= 4.x'
peerDependenciesMeta:
'@babel/core':
optional: true
'@babel/plugin-transform-runtime':
optional: true
'@babel/preset-env':
optional: true
'@babel/preset-typescript':
optional: true
'@babel/runtime':
optional: true
'@swc/core':
optional: true
'@swc/helpers':
optional: true
dependencies:
'@rollup/pluginutils': 4.2.1
'@wessberg/stringutil': 1.0.19
ansi-colors: 4.1.3
browserslist: 4.21.4
browserslist-generator: 1.0.66
compatfactory: 1.0.1_typescript@4.9.4
crosspath: 2.0.0
magic-string: 0.26.7
rollup: 3.9.1
ts-clone-node: 1.0.0_typescript@4.9.4
tslib: 2.4.1
typescript: 4.9.4
dev: true
/rollup/3.9.1:
resolution: {integrity: sha512-GswCYHXftN8ZKGVgQhTFUJB/NBXxrRGgO2NCy6E8s1rwEJ4Q9/VttNqcYfEvx4dTo4j58YqdC3OVztPzlKSX8w==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
fsevents: 2.3.2
dev: true
/semver/7.3.8:
resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
engines: {node: '>=10'}
hasBin: true
dependencies:
lru-cache: 6.0.0
dev: true
/source-map-js/1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
/source-map/0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
/sourcemap-codec/1.4.8:
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
deprecated: Please use @jridgewell/sourcemap-codec instead
/supports-preserve-symlinks-flag/1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
dev: true
/to-fast-properties/2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
/ts-clone-node/1.0.0_typescript@4.9.4:
resolution: {integrity: sha512-/cDYbr2HAXxFNeTT41c/xs/2bhLJjqnYheHsmA3AoHSt+n4JA4t0FL9Lk5O8kWnJ6jeB3kPcUoXIFtwERNzv6Q==}
engines: {node: '>=14.9.0'}
peerDependencies:
typescript: ^3.x || ^4.x
dependencies:
compatfactory: 1.0.1_typescript@4.9.4
typescript: 4.9.4
dev: true
/tslib/2.4.1:
resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==}
dev: true
/typescript/4.9.4:
resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==}
engines: {node: '>=4.2.0'}
hasBin: true
dev: true
/ua-parser-js/1.0.32:
resolution: {integrity: sha512-dXVsz3M4j+5tTiovFVyVqssXBu5HM47//YSOeZ9fQkdDKkfzv2v3PP1jmH6FUyPW+yCSn7aBVK1fGGKNhowdDA==}
dev: true
/update-browserslist-db/1.0.10_browserslist@4.21.4:
resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
dependencies:
browserslist: 4.21.4
escalade: 3.1.1
picocolors: 1.0.0
dev: true
/vite-plugin-vue-setup-extend/0.4.0_vite@4.0.4:
resolution: {integrity: sha512-WMbjPCui75fboFoUTHhdbXzu4Y/bJMv5N9QT9a7do3wNMNHHqrk+Tn2jrSJU0LS5fGl/EG+FEDBYVUeWIkDqXQ==}
peerDependencies:
vite: '>=2.0.0'
dependencies:
'@vue/compiler-sfc': 3.2.45
magic-string: 0.25.9
vite: 4.0.4_@types+node@18.11.18
dev: true
/vite/4.0.4_@types+node@18.11.18:
resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
'@types/node': '>= 14'
less: '*'
sass: '*'
stylus: '*'
sugarss: '*'
terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
less:
optional: true
sass:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
dependencies:
'@types/node': 18.11.18
esbuild: 0.16.14
postcss: 8.4.20
resolve: 1.22.1
rollup: 3.9.1
optionalDependencies:
fsevents: 2.3.2
dev: true
/vue/3.2.45:
resolution: {integrity: sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==}
dependencies:
'@vue/compiler-dom': 3.2.45
'@vue/compiler-sfc': 3.2.45
'@vue/runtime-dom': 3.2.45
'@vue/server-renderer': 3.2.45_vue@3.2.45
'@vue/shared': 3.2.45
/yallist/4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true

5
pnpm-workspace.yaml Normal file
View File

@ -0,0 +1,5 @@
packages:
# all packages in direct subdirs of packages/
- 'packages/*'

43
tsconfig.json Normal file
View File

@ -0,0 +1,43 @@
{
"compilerOptions": {
"strict": true,
"alwaysStrict": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"strictBindCallApply": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "./",
"module": "commonjs",
"jsx": "react-jsx",
"target": "ES6",
"moduleSuffixes": [".ts", ".tsx", ".js", ".jsx", ".gl", ".vsh", ".fsh", ""],
"paths": {
"engine/*": ["./engine/*"],
"ray-lab": ["./engine/RayLab"],
"engine/math": ["./engine/math/Math"],
"engine/kernel": ["./engine/kernel/Kernel"],
"examples/*": ["./examples/*"],
"virtual-renderer": ["./engine/virtual-renderer/VirtualRenderer.ts"]
},
"lib": [
"ESNext",
"DOM"
]
},
"include": [
"./engine/**/*",
"./examples/**/*"
],
"exclude": [
"node_modules",
"build"
]
}