Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Visitlab
Chromatin
chromoskein
Commits
6b297a5b
Commit
6b297a5b
authored
May 10, 2022
by
Matus Talcik
Browse files
fully working template
parent
43b1f7d6
Pipeline
#137636
passed with stage
in 2 minutes and 12 seconds
Changes
16
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
libs/graphics/src/bvh/binned_sah_builder.ts
→
libs/graphics/src/bvh/binned_sah_builder.
worker.
ts
View file @
6b297a5b
File moved
libs/graphics/src/bvh/index.ts
View file @
6b297a5b
export
*
from
"
./shared
"
;
export
*
from
"
./shared
"
;
export
*
from
"
./bounding_volume_hierarchy
"
;
export
*
from
"
./bounding_volume_hierarchy
"
;
export
*
from
"
./binned_sah_builder
"
;
export
*
from
"
./binned_sah_builder.worker
"
;
\ No newline at end of file
\ No newline at end of file
libs/graphics/src/index.ts
View file @
6b297a5b
...
@@ -5,7 +5,7 @@ import { createRenderPipelines } from "./pipelines/index";
...
@@ -5,7 +5,7 @@ import { createRenderPipelines } from "./pipelines/index";
import
{
BindGroupLayouts
,
ComputePipelines
,
PipelineLayouts
,
RenderPipelines
}
from
"
./pipelines/shared
"
;
import
{
BindGroupLayouts
,
ComputePipelines
,
PipelineLayouts
,
RenderPipelines
}
from
"
./pipelines/shared
"
;
import
{
Scene
}
from
"
./scene
"
;
import
{
Scene
}
from
"
./scene
"
;
import
{
createShaderModules
,
ShaderModules
}
from
"
./shaders/index
"
;
import
{
createShaderModules
,
ShaderModules
}
from
"
./shaders/index
"
;
import
{
ChromatinViewport
,
DistanceViewport
}
from
"
./viewports/index
"
;
import
{
ChromatinViewport
,
DistanceViewport
,
Viewport3D
}
from
"
./viewports/index
"
;
export
*
from
"
./cameras/index
"
;
export
*
from
"
./cameras/index
"
;
export
*
from
"
./allocators/index
"
;
export
*
from
"
./allocators/index
"
;
...
@@ -72,6 +72,10 @@ export class GraphicsLibrary {
...
@@ -72,6 +72,10 @@ export class GraphicsLibrary {
});
});
}
}
public
create3DViewport
(
canvas
:
HTMLCanvasElement
|
null
,
scene
:
Scene
|
null
=
null
,
camera
:
OrbitCamera
|
SmoothCamera
|
null
=
null
):
Viewport3D
{
return
new
Viewport3D
(
this
,
canvas
,
scene
,
camera
);
}
public
createChromatinViewport
(
canvas
:
HTMLCanvasElement
|
null
,
scene
:
Scene
|
null
=
null
,
camera
:
OrbitCamera
|
SmoothCamera
|
null
=
null
):
ChromatinViewport
{
public
createChromatinViewport
(
canvas
:
HTMLCanvasElement
|
null
,
scene
:
Scene
|
null
=
null
,
camera
:
OrbitCamera
|
SmoothCamera
|
null
=
null
):
ChromatinViewport
{
return
new
ChromatinViewport
(
this
,
canvas
,
scene
,
camera
);
return
new
ChromatinViewport
(
this
,
canvas
,
scene
,
camera
);
}
}
...
...
libs/graphics/src/scene.ts
View file @
6b297a5b
...
@@ -222,7 +222,7 @@ export class Scene {
...
@@ -222,7 +222,7 @@ export class Scene {
const
copyOfObjectsBuffer
=
this
.
_buffer
.
cpuBuffer
().
slice
(
this
.
_buffer
.
data
.
byteOffset
,
this
.
_buffer
.
data
.
byteOffset
+
this
.
_buffer
.
data
.
byteLength
);
const
copyOfObjectsBuffer
=
this
.
_buffer
.
cpuBuffer
().
slice
(
this
.
_buffer
.
data
.
byteOffset
,
this
.
_buffer
.
data
.
byteOffset
+
this
.
_buffer
.
data
.
byteLength
);
// console.timeEnd('scene::buildBVH::bboxes');
// console.timeEnd('scene::buildBVH::bboxes');
this
.
bvhWorker
=
new
Worker
(
new
URL
(
'
./bvh/binned_sah_builder.ts
'
,
import
.
meta
.
url
));
this
.
bvhWorker
=
new
Worker
(
new
URL
(
'
./bvh/binned_sah_builder.
worker.
ts
'
,
import
.
meta
.
url
));
this
.
bvhWorker
.
onmessage
=
({
data
:
{
result
}
})
=>
{
this
.
bvhWorker
.
onmessage
=
({
data
:
{
result
}
})
=>
{
// console.time('scene::buildBVH::Finish');
// console.time('scene::buildBVH::Finish');
if
(
result
==
null
)
{
if
(
result
==
null
)
{
...
...
libs/parsing/index.ts
0 → 100644
View file @
6b297a5b
export
*
from
'
./shared
'
;
\ No newline at end of file
libs/parsing/parsePDB.ts
0 → 100644
View file @
6b297a5b
import
{
vec3
}
from
"
gl-matrix
"
;
import
{
BoundingBoxEmpty
,
BoundingBoxExtendByPoint
}
from
"
../graphics/shared
"
;
const
ATOM_NAME
=
'
ATOM
'
;
const
RESIDUE_NAME
=
'
SEQRES
'
;
export
class
Atom
{
serial
:
number
|
null
=
null
;
name
:
string
|
null
=
null
;
altLoc
:
string
|
null
=
null
;
resName
:
string
|
null
=
null
;
chainID
:
string
|
null
=
null
;
resSeq
:
number
|
null
=
null
;
// Also CHROMOSOME
iCode
:
string
|
null
=
null
;
x
:
number
|
null
=
null
;
y
:
number
|
null
=
null
;
z
:
number
|
null
=
null
;
occupancy
:
number
|
null
=
null
;
tempFactor
:
number
|
null
=
null
;
element
:
string
|
null
=
null
;
charge
:
string
|
null
=
null
;
}
export
class
SeqResEntry
{
serNum
:
number
|
null
=
null
;
chainID
:
string
|
null
=
null
;
numRes
:
number
|
null
=
null
;
resNames
:
Array
<
string
>
=
[];
}
export
class
Residue
{
id
:
number
|
null
=
null
;
serNum
:
number
|
null
=
null
;
chainID
:
string
|
null
=
null
;
resName
:
string
|
null
=
null
;
atoms
:
Array
<
Atom
>
=
[];
}
export
type
ChromatinModel
=
{
atoms
:
Array
<
{
x
:
number
,
y
:
number
,
z
:
number
}
>
;
ranges
:
Array
<
{
name
:
string
,
from
:
number
,
to
:
number
}
>
;
normalizeCenter
:
vec3
;
normalizeScale
:
number
;
};
/**
* Parses the given PDB string into json
* @param {String} pdb
* @returns {Object}
*/
export
function
parsePdb
(
pdb
:
string
):
Array
<
ChromatinModel
>
{
const
pdbLines
=
pdb
.
split
(
'
\n
'
);
let
atoms
:
Array
<
{
x
:
number
,
y
:
number
,
z
:
number
}
>
=
[];
// Connectivity
let
connectivityBitset
:
Array
<
0
|
1
>
=
new
Array
(
pdbLines
.
length
).
fill
(
0
);
let
names
:
Array
<
string
>
=
[];
// Iterate each line looking for atoms
let
stop
=
false
;
pdbLines
.
forEach
((
pdbLine
)
=>
{
if
(
pdbLine
.
length
<
6
)
{
return
;
}
const
identification
=
pdbLine
.
substring
(
0
,
6
);
if
(
identification
===
ATOM_NAME
||
identification
===
'
HETATM
'
)
{
if
(
!
stop
)
{
atoms
.
push
({
x
:
parseFloat
(
pdbLine
.
substring
(
30
,
38
)),
y
:
parseFloat
(
pdbLine
.
substring
(
38
,
46
)),
z
:
parseFloat
(
pdbLine
.
substring
(
46
,
54
))
});
}
names
.
push
(
`chr
${
pdbLine
.
substring
(
17
,
21
).
trim
()}
`
)
// http://www.wwpdb.org/documentation/file-format-content/format33/sect9.html#ATOM
// if (!stop) {
// atoms.push({
// serial: parseInt(pdbLine.substring(6, 11)),
// name: pdbLine.substring(12, 16).trim(),
// altLoc: pdbLine.substring(16, 17).trim(),
// resName: pdbLine.substring(17, 20).trim(),
// chainID: pdbLine.substring(21, 22).trim(),
// resSeq: parseInt(pdbLine.substring(22, 26)),
// iCode: pdbLine.substring(26, 27).trim(),
// x: parseFloat(pdbLine.substring(30, 38)),
// y: parseFloat(pdbLine.substring(38, 46)),
// z: parseFloat(pdbLine.substring(46, 54)),
// occupancy: parseFloat(pdbLine.substring(54, 60)),
// tempFactor: parseFloat(pdbLine.substring(60, 66)),
// element: pdbLine.substring(76, 78).trim(),
// charge: pdbLine.substring(78, 80).trim(),
// });
// }
}
else
if
(
identification
===
'
CONECT
'
)
{
const
from
=
parseInt
(
pdbLine
.
substring
(
6
,
11
))
-
1
;
const
to
=
parseInt
(
pdbLine
.
substring
(
11
,
16
))
-
1
;
if
(
to
-
from
==
1
)
{
connectivityBitset
[
from
]
=
1
;
}
}
else
if
(
identification
===
'
ENDMDL
'
)
{
stop
=
true
;
}
});
const
ranges
:
Array
<
{
name
:
string
,
from
:
number
,
to
:
number
}
>
=
[];
connectivityBitset
=
connectivityBitset
.
slice
(
0
,
atoms
.
length
);
let
expandingRange
=
false
;
for
(
let
i
=
0
;
i
<
connectivityBitset
.
length
;
i
++
)
{
const
currentValue
=
connectivityBitset
[
i
];
if
(
expandingRange
&&
i
==
connectivityBitset
.
length
-
1
&&
currentValue
===
1
)
{
ranges
[
ranges
.
length
-
1
].
to
=
connectivityBitset
.
length
;
break
;
}
if
(
currentValue
===
0
&&
!
expandingRange
)
continue
;
if
(
currentValue
===
1
&&
expandingRange
)
continue
;
if
(
currentValue
===
1
&&
!
expandingRange
)
{
// Start new range
ranges
.
push
({
name
:
names
[
i
],
from
:
i
,
to
:
i
+
1
});
expandingRange
=
true
;
}
if
(
currentValue
===
0
&&
expandingRange
)
{
// End the range
ranges
[
ranges
.
length
-
1
].
to
=
i
;
expandingRange
=
false
;
}
}
// Normalize to [-1.0, 1.0] and center
// Build bounding box
const
bb
=
BoundingBoxEmpty
();
let
points
=
atoms
.
map
(
v
=>
vec3
.
fromValues
(
v
.
x
,
v
.
y
,
v
.
z
));
for
(
const
point
of
points
)
{
BoundingBoxExtendByPoint
(
bb
,
point
);
}
points
=
points
.
map
(
v
=>
vec3
.
sub
(
vec3
.
create
(),
v
,
bb
.
center
));
const
bbSizeLengthsVec3
=
vec3
.
sub
(
vec3
.
create
(),
bb
.
max
,
bb
.
min
);
const
bbSizeLengths
=
[
Math
.
abs
(
bbSizeLengthsVec3
[
0
]),
Math
.
abs
(
bbSizeLengthsVec3
[
1
]),
Math
.
abs
(
bbSizeLengthsVec3
[
2
])];
const
maxLength
=
Math
.
max
(...
bbSizeLengths
);
const
scale
=
1.0
/
maxLength
;
points
=
points
.
map
(
v
=>
vec3
.
scale
(
vec3
.
create
(),
v
,
scale
));
atoms
=
atoms
.
map
((
a
,
i
)
=>
{
return
{
...
a
,
x
:
points
[
i
][
0
],
y
:
points
[
i
][
1
],
z
:
points
[
i
][
2
]
};
});
return
[{
// Raw data from pdb
atoms
,
// Connectivity
ranges
,
// Normalize
normalizeCenter
:
bb
.
center
,
normalizeScale
:
scale
}];
}
libs/parsing/shared.ts
0 → 100644
View file @
6b297a5b
import
Papa
,
{
parse
}
from
"
papaparse
"
;
import
{
ChromatinModel
,
parsePdb
}
from
"
./parsePDB
"
;
// import gff from "@gmod/gff";
import
{
toNumber
}
from
"
lodash
"
;
import
{
vec3
}
from
"
gl-matrix
"
;
export
const
enum
FileType
{
PDB
,
CSV
,
}
export
const
enum
CSVDelimiter
{
Comma
=
'
,
'
,
Tabulator
=
'
\t
'
,
Space
=
'
'
,
}
export
const
enum
FileState
{
NoFile
,
ParseError
,
Downloading
,
Parsing
,
Done
,
}
export
type
ParsePDBConfiguration
=
{
type
:
FileType
.
PDB
};
export
type
ParseCSVConfiguration
=
{
type
:
FileType
.
CSV
,
delimiter
:
CSVDelimiter
,
hasHeader
:
boolean
,
};
export
type
ParseConfiguration
=
ParsePDBConfiguration
|
ParseCSVConfiguration
;
export
type
ParseResultType
=
'
CSV
'
|
'
PDB
'
;
export
type
ParseResult
=
ParseResultCSV
|
ParseResultPDB
;
export
interface
IParseResult
{
type
:
ParseResultType
;
}
export
interface
ParseResultCSV
extends
IParseResult
{
type
:
'
CSV
'
;
columns
:
Array
<
string
|
number
>
;
rows
:
Array
<
Record
<
string
,
string
>>
;
}
export
interface
ParseResultPDB
extends
IParseResult
{
type
:
'
PDB
'
;
atoms
:
Array
<
{
x
:
number
,
y
:
number
,
z
:
number
}
>
;
normalizeCenter
:
vec3
;
normalizeScale
:
number
;
ranges
:
Array
<
{
name
:
string
,
from
:
number
,
to
:
number
}
>
;
}
export
function
fileStateToText
(
state
:
FileState
):
string
{
switch
(
state
)
{
case
FileState
.
NoFile
:
return
"
No file is selected
"
;
case
FileState
.
ParseError
:
return
"
There was an unknown error during parsing
"
;
case
FileState
.
Downloading
:
return
"
Downloading file
"
;
case
FileState
.
Parsing
:
return
"
File is being parsed
"
;
case
FileState
.
Done
:
return
"
Parsing has completed
"
;
}
}
export
function
parseToRows
(
content
:
string
,
config
:
ParseConfiguration
):
Array
<
ParseResult
>
{
switch
(
config
.
type
)
{
case
FileType
.
PDB
:
return
parsePDBToObjects
(
content
,
config
as
ParsePDBConfiguration
);
case
FileType
.
CSV
:
return
[
parseCSVToObjects
(
content
,
config
as
ParseCSVConfiguration
)];
}
}
function
parsePDBToObjects
(
content
:
string
,
config
:
ParsePDBConfiguration
):
Array
<
ParseResultPDB
>
{
const
parsed
=
parsePdb
(
content
);
return
parsed
.
map
((
p
:
ChromatinModel
)
=>
{
return
{
type
:
'
PDB
'
,
atoms
:
p
.
atoms
,
normalizeCenter
:
p
.
normalizeCenter
,
normalizeScale
:
p
.
normalizeScale
,
ranges
:
p
.
ranges
,
}
});
}
function
parseCSVToObjects
(
content
:
string
,
config
:
ParseCSVConfiguration
):
ParseResultCSV
{
const
result
:
ParseResultCSV
=
{
type
:
'
CSV
'
,
columns
:
[],
rows
:
[],
};
let
delimiter
;
const
header
=
config
.
hasHeader
;
switch
(
config
.
delimiter
)
{
case
CSVDelimiter
.
Comma
:
delimiter
=
'
,
'
;
break
;
case
CSVDelimiter
.
Space
:
delimiter
=
'
'
;
break
;
case
CSVDelimiter
.
Tabulator
:
delimiter
=
'
\t
'
;
break
;
}
const
papaResults
=
Papa
.
parse
(
content
,
{
delimiter
,
header
,
});
if
(
header
&&
papaResults
.
meta
[
'
fields
'
])
{
result
.
columns
=
papaResults
.
meta
[
'
fields
'
];
}
else
{
const
row
=
papaResults
.
data
[
0
]
as
Array
<
unknown
>
;
result
.
columns
=
Array
.
from
({
length
:
row
.
length
},
(
_
,
i
)
=>
i
+
1
);
}
if
(
header
)
{
for
(
let
i
=
0
;
i
<
papaResults
.
data
.
length
;
i
++
)
{
result
.
rows
.
push
(
papaResults
.
data
[
i
]
as
unknown
as
Record
<
string
,
string
>
);
}
}
else
{
for
(
let
i
=
0
;
i
<
papaResults
.
data
.
length
;
i
++
)
{
const
row
=
papaResults
.
data
[
i
]
as
Array
<
unknown
>
;
const
entries
=
new
Map
<
string
,
string
>
();
for
(
let
i
=
0
;
i
<
row
.
length
;
i
++
)
{
const
value
=
row
[
i
];
entries
.
set
(
String
(
i
+
1
),
String
(
value
));
}
result
.
rows
.
push
(
Object
.
fromEntries
(
entries
));
}
}
return
result
;
}
export
function
parseResultToXYZ
(
parseResult
:
ParseResultCSV
,
columns
:
Array
<
string
|
number
>
):
Array
<
{
x
:
number
,
y
:
number
,
z
:
number
}
>
{
const
positions
:
Array
<
{
x
:
number
,
y
:
number
,
z
:
number
}
>
=
[];
for
(
let
i
=
0
;
i
<
parseResult
.
rows
.
length
;
i
++
)
{
const
row
=
parseResult
.
rows
[
i
];
positions
.
push
({
x
:
parseFloat
(
row
[
columns
[
0
]]),
y
:
parseFloat
(
row
[
columns
[
1
]]),
z
:
parseFloat
(
row
[
columns
[
2
]])
});
}
return
positions
;
}
export
function
parseResultToSparse1D
(
parseResult
:
ParseResultCSV
,
columns
:
Array
<
string
|
number
>
):
Array
<
{
from
:
number
,
to
:
number
,
value
:
number
}
>
{
const
data
:
Array
<
{
from
:
number
,
to
:
number
,
value
:
number
}
>
=
[];
for
(
let
i
=
0
;
i
<
parseResult
.
rows
.
length
;
i
++
)
{
const
row
=
parseResult
.
rows
[
i
];
data
.
push
({
from
:
parseFloat
(
row
[
columns
[
0
]]),
to
:
parseFloat
(
row
[
columns
[
1
]]),
value
:
parseFloat
(
row
[
columns
[
2
]])
});
}
return
data
;
}
export
function
parseResultToSparseDistanceMatrix
(
parseResult
:
ParseResultCSV
,
columns
:
Array
<
string
|
number
>
):
Array
<
{
from
:
number
,
to
:
number
,
distance
:
number
}
>
{
const
data
:
Array
<
{
from
:
number
,
to
:
number
,
distance
:
number
}
>
=
[];
for
(
let
i
=
0
;
i
<
parseResult
.
rows
.
length
;
i
++
)
{
const
row
=
parseResult
.
rows
[
i
];
data
.
push
({
from
:
parseFloat
(
row
[
columns
[
0
]]),
to
:
parseFloat
(
row
[
columns
[
1
]]),
distance
:
parseFloat
(
row
[
columns
[
2
]])
});
}
return
data
;
}
//todo: screw the lib and rewrite
// export function parseGFF(content: string): Array<{
// seqId: string | null,
// from?: number | null, to?: number | null,
// score?: number | null,
// strand?: "+" | "-" | "?" | "." | null
// attributes: Record<string, string[] | undefined>
// }> {
// const annotations = gff.parseStringSync(content);
// const parsedAnnotations = [];
// for (const annotation of annotations) {
// if (!(Symbol.iterator in Object.values(annotation))) {
// continue;
// }
// for (const feature of annotation) {
// parsedAnnotations.push({
// seqId: feature.seq_id,
// from: feature.start,
// to: feature.end,
// score: feature.score,
// strand: feature.strand as "+" | "-" | "?" | "." | null,
// attributes: feature.attributes ?? {}
// })
// }
// }
// return parsedAnnotations;
// }
export
type
ParseResultBED
=
Array
<
{
chromosome
:
string
,
from
:
number
,
to
:
number
,
attributes
:
Record
<
number
,
string
>
}
>
export
function
parseBED
(
content
:
string
,
delimiter
:
CSVDelimiter
.
Space
|
CSVDelimiter
.
Tabulator
):
ParseResultBED
{
const
parseResults
=
parseCSVToObjects
(
content
,
{
type
:
FileType
.
CSV
,
hasHeader
:
false
,
delimiter
:
delimiter
})
as
ParseResultCSV
;
const
annotations
=
parseResults
.
rows
.
filter
(
r
=>
r
[
1
]
!=
"
browser
"
&&
r
[
1
]
!=
"
track
"
&&
Object
.
keys
(
r
).
length
!=
1
)
return
annotations
.
map
(
a
=>
{
return
{
chromosome
:
a
[
1
],
from
:
toNumber
(
a
[
2
]),
to
:
toNumber
(
a
[
3
]),
attributes
:
a
,
...
a
}
}
);
}
\ No newline at end of file
template/package-lock.json
View file @
6b297a5b
...
@@ -18,8 +18,10 @@
...
@@ -18,8 +18,10 @@
"react-dom"
:
"^18.1.0"
"react-dom"
:
"^18.1.0"
},
},
"devDependencies"
:
{
"devDependencies"
:
{
"@types/lodash"
:
"^4.14.182"
,
"@types/react"
:
"^18.0.9"
,
"@types/react"
:
"^18.0.9"
,
"@types/react-dom"
:
"^18.0.3"
,
"@types/react-dom"
:
"^18.0.3"
,
"esbuild-plugin-inline-worker"
:
"^0.1.1"
,
"typescript"
:
"^4.6.4"
"typescript"
:
"^4.6.4"
}
}
},
},
...
@@ -42,6 +44,12 @@
...
@@ -42,6 +44,12 @@
"@babel/runtime"
:
"^7.10.3"
"@babel/runtime"
:
"^7.10.3"
}
}
},
},
"node_modules/@types/lodash"
:
{
"version"
:
"4.14.182"
,
"resolved"
:
"https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz"
,
"integrity"
:
"sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q=="
,
"dev"
:
true
},
"node_modules/@types/pako"
:
{
"node_modules/@types/pako"
:
{
"version"
:
"1.0.3"
,
"version"
:
"1.0.3"
,
"resolved"
:
"https://registry.npmjs.org/@types/pako/-/pako-1.0.3.tgz"
,
"resolved"
:
"https://registry.npmjs.org/@types/pako/-/pako-1.0.3.tgz"
,
...
@@ -94,6 +102,12 @@
...
@@ -94,6 +102,12 @@
"resolved"
:
"https://registry.npmjs.org/canny-edge-detector/-/canny-edge-detector-1.0.0.tgz"
,
"resolved"
:
"https://registry.npmjs.org/canny-edge-detector/-/canny-edge-detector-1.0.0.tgz"
,
"integrity"
:
"sha512-SpewmkHDE1PbJ1/AVAcpvZKOufYpUXT0euMvhb5C4Q83Q9XEOmSXC+yR7jl3F4Ae1Ev6OtQKbFgdcPrOdHjzQg=="
"integrity"
:
"sha512-SpewmkHDE1PbJ1/AVAcpvZKOufYpUXT0euMvhb5C4Q83Q9XEOmSXC+yR7jl3F4Ae1Ev6OtQKbFgdcPrOdHjzQg=="
},
},
"node_modules/commondir"
:
{
"version"
:
"1.0.1"
,
"resolved"
:
"https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz"
,
"integrity"
:
"sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs="
,
"dev"
:
true
},
"node_modules/csstype"
:
{
"node_modules/csstype"
:
{
"version"
:
"3.0.11"
,
"version"
:
"3.0.11"
,
"resolved"
:
"https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz"
,
"resolved"
:
"https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz"
,
...
@@ -374,6 +388,16 @@
...
@@ -374,6 +388,16 @@
"node"
:
">=12"
"node"
:
">=12"
}
}
},
},
"node_modules/esbuild-plugin-inline-worker"
:
{
"version"
:
"0.1.1"
,
"resolved"
:
"https://registry.npmjs.org/esbuild-plugin-inline-worker/-/esbuild-plugin-inline-worker-0.1.1.tgz"
,
"integrity"
:
"sha512-VmFqsQKxUlbM51C1y5bRiMeyc1x2yTdMXhKB6S//++g9aCBg8TfGsbKxl5ZDkCGquqLY+RmEk93TBNd0i35dPA=="
,
"dev"
:
true
,
"dependencies"
:
{
"esbuild"
:
"latest"
,
"find-cache-dir"
:
"^3.3.1"
}
},
"node_modules/esbuild-sunos-64"
:
{
"node_modules/esbuild-sunos-64"
:
{
"version"
:
"0.14.38"
,
"version"
:
"0.14.38"
,
"resolved"
:
"https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.38.tgz"
,
"resolved"
:
"https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.38.tgz"
,
...
@@ -497,6 +521,36 @@
...
@@ -497,6 +521,36 @@
"node"
:
">=6"
"node"
:
">=6"
}
}
},
},
"node_modules/find-cache-dir"
:
{
"version"
:
"3.3.2"
,
"resolved"
:
"https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz"
,
"integrity"
:
"sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig=="
,
"dev"
:
true
,
"dependencies"
:
{
"commondir"
:
"^1.0.1"
,
"make-dir"
:
"^3.0.2"
,
"pkg-dir"
:
"^4.1.0"
},
"engines"
:
{
"node"
:
">=8"
},
"funding"
:
{
"url"
:
"https://github.com/avajs/find-cache-dir?sponsor=1"
}
},
"node_modules/find-up"
:
{
"version"
:
"4.1.0"
,
"resolved"
:
"https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz"
,
"integrity"
:
"sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="
,
"dev"
:
true
,
"dependencies"
:
{
"locate-path"
:
"^5.0.0"
,
"path-exists"
:
"^4.0.0"
},
"engines"
:
{
"node"
:
">=8"
}
},
"node_modules/gl-matrix"
:
{
"node_modules/gl-matrix"
:
{
"version"
:
"3.4.3"
,
"version"
:
"3.4.3"
,
"resolved"
:
"https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz"
,
"resolved"
:
"https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz"
,
...
@@ -610,6 +664,18 @@
...
@@ -610,6 +664,18 @@
"resolved"
:
"https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
,
"resolved"
:
"https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
,
"integrity"
:
"sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
"integrity"
:
"sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
},
"node_modules/locate-path"
:
{
"version"
:
"5.0.0"
,
"resolved"
:
"https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz"
,
"integrity"
:
"sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="
,
"dev"
:
true
,
"dependencies"
:
{