├── .gitignore ├── .nvmrc ├── .parcelrc ├── README.md ├── package.json ├── src ├── Cloth.ts ├── Collison.ts ├── Constraint.ts ├── GPUBufferFactory.ts ├── Hash.ts ├── ObjLoader.ts ├── PerspectiveCamera.ts ├── PhysicsObject.ts ├── Transformation.ts ├── WebGPUCanvas.ts ├── app.ts ├── index.html ├── math.ts ├── programs │ ├── DebuggerProgram.ts │ ├── DefaultProgram.ts │ ├── Program.ts │ ├── constants.ts │ └── shaders │ │ ├── debuggerShader.ts │ │ └── defaultShader.ts ├── styles.css └── types.ts ├── static └── cloth_20_30_l.obj ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .parcel-cache 4 | static/objs -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 16.15.0 -------------------------------------------------------------------------------- /.parcelrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@parcel/config-default", 3 | "reporters": ["...", "parcel-reporter-static-files-copy"] 4 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebGPU XPBD Cloth Simulator 2 | 3 | This is a WebGPU Cloth Simulator that uses XPBD (extended position based dynamics) with small step sizes. 4 | 5 | ![Cloth 09_06_2022](https://user-images.githubusercontent.com/24990748/188770782-ee621e1c-bb6d-4b1a-99e6-c37dd77bd287.gif) 6 | 7 | This relies heavily on the following papers: 8 | 9 | - [XPBD: Position-Based Simulation of Compliant Constrained Dynamics - Macklin et. al - NVIDIA](https://matthias-research.github.io/pages/publications/XPBD.pdf) 10 | - [Small Steps in Physics Simulation, Macklin et. al - NVIDIA](https://matthias-research.github.io/pages/publications/smallsteps.pdf) 11 | - [A Survey on Position Based Dynamics, 2017](http://mmacklin.com/2017-EG-CourseNotes.pdf) 12 | 13 | As well as code snippets from: 14 | 15 | - [Cloth simulation code - Matthias Müller](https://github.com/matthias-research/pages/blob/master/tenMinutePhysics/14-cloth.html) 16 | 17 | ## Development 18 | 19 | The following steps describe how to run this simulation locally. 20 | 21 | **Note** - This has only been tested on Windows (specifically with WSL2). 22 | 23 | ### Accessing the WebGPU API 24 | 25 | WebGPU is currently a developmental feature, and thus requires a browser that enables access to it. [Google Canary](https://www.google.com/chrome/canary/) is a good candidate. To enable the correct features in your browser, please do the following: 26 | 27 | - Enable the `#enable-unsafe-webgpu` flag in about://flags. 28 | 29 | ### Running the dev server 30 | 31 | With yarn installed, run the following: 32 | 33 | ``` 34 | yarn 35 | yarn start 36 | ``` 37 | 38 | ## Current implementation 39 | 40 | - [x] [XPBD Simulation Loop](https://www.carmencincotti.com/2022-08-08/xpbd-extended-position-based-dynamics/) 41 | - [x] [Small Steps](https://www.carmencincotti.com/2022-08-08/xpbd-extended-position-based-dynamics/) 42 | - [x] [Constraints - Distance](https://www.carmencincotti.com/2022-08-22/the-distance-constraint-of-xpbd/) 43 | - [x] [Constraints - Fast Performant Bending](https://www.carmencincotti.com/2022-09-05/the-most-performant-bending-constraint-of-xpbd/) 44 | - [x] [Constraints - Isometric Bending](https://www.carmencincotti.com/2022-08-29/the-isometric-bending-constraint-of-xpbd/) 45 | - [ ] Constraints - Angular Bending 46 | - [x] [Constraints - Collisions (Self)]() 47 | - [ ] Constraints - Collisions (External) 48 | - [ ] Damping 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloth_simulator", 3 | "version": "1.0.0", 4 | "description": "A simulator for cloth.", 5 | "author": "Carmen Cincotti ", 6 | "license": " GPL-3.0-only", 7 | "private": true, 8 | "scripts": { 9 | "start": "parcel src/index.html", 10 | "build": "parcel build" 11 | }, 12 | "dependencies": { 13 | "gl-matrix": "^3.4.3" 14 | }, 15 | "devDependencies": { 16 | "@webgpu/types": "^0.1.17", 17 | "parcel": "^2.5.0", 18 | "parcel-reporter-static-files-copy": "^1.3.4", 19 | "typescript": "^4.6.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Cloth.ts: -------------------------------------------------------------------------------- 1 | import { ClothPhysicsObject } from "./PhysicsObject"; 2 | import { Mesh } from "./types"; 3 | 4 | /** 5 | * Cloth that hangs (like from a clothesline) 6 | * Uses position based dynamics constraints 7 | * 8 | * It is the user's responsibility to register constraints within the app. 9 | */ 10 | export default class Cloth extends ClothPhysicsObject { 11 | constructor(mesh: Mesh, thickness: number) { 12 | super(mesh, thickness); 13 | this.init(); 14 | } 15 | 16 | private init() { 17 | // Set top of cloth to have a mass of 0 to hold still 18 | // in order to get hanging from clothesline visual 19 | { 20 | // Variables to store top row 21 | let minX = Number.MAX_VALUE; 22 | let maxX = -Number.MAX_VALUE; 23 | let maxY = -Number.MAX_VALUE; 24 | 25 | for (let i = 0; i < this.numParticles; i++) { 26 | minX = Math.min(minX, this.positions[3 * i]); 27 | maxX = Math.max(maxX, this.positions[3 * i]); 28 | maxY = Math.max(maxY, this.positions[3 * i + 1]); 29 | } 30 | 31 | // Thickness of the edge to zero out(?) 32 | const eps = 0.000001; 33 | 34 | for (let i = 0; i < this.numParticles; i++) { 35 | const x = this.positions[3 * i]; 36 | const y = this.positions[3 * i + 1]; 37 | if (y > maxY - eps && (x < minX + eps || x > maxX - eps)) 38 | // if (y > maxY - eps) 39 | this.invMass[i] = 0.0; 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Collison.ts: -------------------------------------------------------------------------------- 1 | import { Hash } from "./Hash"; 2 | import { 3 | vecAdd, 4 | vecDistSquared, 5 | vecLengthSquared, 6 | vecScale, 7 | vecSetDiff, 8 | vecSetSum, 9 | } from "./math"; 10 | 11 | export abstract class Collision { 12 | protected positions: Float32Array; 13 | protected prevPositions: Float32Array; 14 | protected invMass: Float32Array; 15 | protected vecs: Float32Array; 16 | protected numParticles: number; 17 | 18 | constructor( 19 | positions: Float32Array, 20 | prevPositions: Float32Array, 21 | invMass: Float32Array 22 | ) { 23 | this.positions = positions; 24 | this.prevPositions = prevPositions; 25 | this.invMass = invMass; 26 | this.vecs = new Float32Array(12); 27 | this.numParticles = positions.length / 3; 28 | } 29 | 30 | /** 31 | * Updates positions during an animation step 32 | */ 33 | abstract solve(dt: number): void; 34 | } 35 | /** 36 | * Collision constraints specfic to cloth 37 | */ 38 | 39 | export default class ClothSelfCollision extends Collision { 40 | private thickness: number; 41 | private restPositions: Float32Array; 42 | private hash: Hash; 43 | constructor( 44 | positions: Float32Array, 45 | prevPositions: Float32Array, 46 | invMass: Float32Array, 47 | thickness: number, 48 | hash: Hash 49 | ) { 50 | super(positions, prevPositions, invMass); 51 | this.thickness = thickness; 52 | this.restPositions = new Float32Array(positions); 53 | this.hash = hash; 54 | } 55 | solve(dt: number) { 56 | // Square to compare with dist2 57 | // We can do this to save a sqrt operation 58 | const thickness2 = this.thickness * this.thickness; 59 | 60 | for (let id0 = 0; id0 < this.numParticles; id0++) { 61 | if (this.invMass[id0] == 0.0) continue; 62 | const adjacentParticles = this.hash.getAdjacentParticles(id0); 63 | 64 | for (const id1 of adjacentParticles) { 65 | if (this.invMass[id1] == 0.0) continue; 66 | 67 | // Determine if the distance between the two particles is smaller than 68 | // the thickness... which would signify that the particles are overlapping 69 | // each other. 70 | vecSetDiff(this.vecs, 0, this.positions, id1, this.positions, id0); 71 | const dist2 = vecLengthSquared(this.vecs, 0); 72 | if (dist2 > thickness2 || dist2 === 0.0) continue; 73 | 74 | // If the particles have smaller rest distances than 75 | // the thickness, use that to make the position correction. 76 | const restDist2 = vecDistSquared( 77 | this.restPositions, 78 | id0, 79 | this.restPositions, 80 | id1 81 | ); 82 | 83 | let minDist = this.thickness; 84 | if (dist2 > restDist2) continue; 85 | if (restDist2 < thickness2) minDist = Math.sqrt(restDist2); 86 | 87 | // Position correction 88 | // Now finally do the sqrt op 89 | const dist = Math.sqrt(dist2); 90 | const correctionDist = minDist - dist; 91 | if (correctionDist > 0.0) { 92 | vecScale(this.vecs, 0, correctionDist / dist); 93 | vecAdd(this.positions, id0, this.vecs, 0, -0.5); 94 | vecAdd(this.positions, id1, this.vecs, 0, 0.5); 95 | 96 | // Friction Handling 97 | const dampingCoefficient = -1; 98 | 99 | if (dampingCoefficient > 0) { 100 | // velocities 101 | vecSetDiff( 102 | this.vecs, 103 | 0, 104 | this.positions, 105 | id0, 106 | this.prevPositions, 107 | id0 108 | ); 109 | vecSetDiff( 110 | this.vecs, 111 | 1, 112 | this.positions, 113 | id1, 114 | this.prevPositions, 115 | id1 116 | ); 117 | 118 | // average velocity 119 | vecSetSum(this.vecs, 2, this.vecs, 0, this.vecs, 1, 0.5); 120 | 121 | // velocity corrections by modifying them. 122 | vecSetDiff(this.vecs, 0, this.vecs, 2, this.vecs, 0); 123 | vecSetDiff(this.vecs, 1, this.vecs, 2, this.vecs, 1); 124 | 125 | // add corrections 126 | vecAdd(this.positions, id0, this.vecs, 0, dampingCoefficient); 127 | vecAdd(this.positions, id1, this.vecs, 1, dampingCoefficient); 128 | } 129 | } 130 | } 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Constraint.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * XPBD Constraints 3 | */ 4 | 5 | import { mat4 } from "gl-matrix"; 6 | import { 7 | DataArray, 8 | multiply4dColumnVectorByTranspose, 9 | vecAdd, 10 | vecCopy, 11 | vecDistSquared, 12 | vecDot, 13 | vecLengthSquared, 14 | vecNorm, 15 | vecScale, 16 | vecSetCross, 17 | vecSetDiff, 18 | vecSetZero, 19 | } from "./math"; 20 | 21 | /** 22 | * Constraint parent class in which all constraints 23 | * dervive from 24 | */ 25 | export abstract class Constraint { 26 | protected positions: Float32Array; 27 | protected invMass: Float32Array; 28 | protected indices: Uint16Array; 29 | protected neighbors: Float32Array; 30 | protected grads: Float32Array; 31 | protected compliance: number; 32 | 33 | constructor( 34 | positions: Float32Array, 35 | invMass: Float32Array, 36 | indices: Uint16Array, 37 | neighbors: Float32Array, 38 | compliance: number 39 | ) { 40 | this.positions = positions; 41 | this.invMass = invMass; 42 | this.indices = indices; 43 | this.neighbors = neighbors; 44 | this.compliance = compliance; 45 | this.grads = new Float32Array(12); 46 | } 47 | 48 | /** 49 | * Updates positions during an animation step 50 | */ 51 | abstract solve(dt: number): void; 52 | } 53 | 54 | export class ConstraintFactory { 55 | private positions: Float32Array; 56 | private invMass: Float32Array; 57 | private indices: Uint16Array; 58 | private neighbors: Float32Array; 59 | constructor( 60 | positions: Float32Array, 61 | invMass: Float32Array, 62 | indices: Uint16Array, 63 | neighbors: Float32Array 64 | ) { 65 | this.positions = positions; 66 | this.invMass = invMass; 67 | this.indices = indices; 68 | this.neighbors = neighbors; 69 | } 70 | 71 | createDistanceConstraint(compliance: number) { 72 | return new DistanceConstraint( 73 | this.positions, 74 | this.invMass, 75 | this.indices, 76 | this.neighbors, 77 | compliance 78 | ); 79 | } 80 | 81 | createPerformantBendingConstraint(compliance: number) { 82 | return new PerformantBendingConstraint( 83 | this.positions, 84 | this.invMass, 85 | this.indices, 86 | this.neighbors, 87 | compliance 88 | ); 89 | } 90 | 91 | createIsometricBendingConstraint(compliance: number) { 92 | return new IsometricBendingConstraint( 93 | this.positions, 94 | this.invMass, 95 | this.indices, 96 | this.neighbors, 97 | compliance 98 | ); 99 | } 100 | } 101 | 102 | /** 103 | * Distance constraint as defined in http://mmacklin.com/2017-EG-CourseNotes.pdf 104 | */ 105 | export class DistanceConstraint extends Constraint { 106 | edgeIds: Uint16Array; 107 | edgeLengths: Float32Array; 108 | 109 | constructor( 110 | positions: Float32Array, 111 | invMass: Float32Array, 112 | indices: Uint16Array, 113 | neighbors: Float32Array, 114 | compliance: number 115 | ) { 116 | super(positions, invMass, indices, neighbors, compliance); 117 | 118 | this.edgeIds = this.getEdgeIds(); 119 | this.edgeLengths = new Float32Array(this.edgeIds.length / 2); 120 | this.initializeEdgeLengths(); 121 | } 122 | 123 | solve(dt: number) { 124 | const alpha = this.compliance / dt / dt; 125 | for (let i = 0; i < this.edgeLengths.length; i++) { 126 | const id0 = this.edgeIds[2 * i]; 127 | const id1 = this.edgeIds[2 * i + 1]; 128 | const w0 = this.invMass[id0]; 129 | const w1 = this.invMass[id1]; 130 | const w = w0 + w1; 131 | if (w == 0.0) continue; 132 | 133 | vecSetDiff(this.grads, 0, this.positions, id0, this.positions, id1); 134 | const len = Math.sqrt(vecLengthSquared(this.grads, 0)); 135 | if (len == 0.0) continue; 136 | const restLen = this.edgeLengths[i]; 137 | const C = len - restLen; 138 | const normalizingFactor = 1.0 / len; 139 | const s = (-C / (w + alpha)) * normalizingFactor; 140 | vecAdd(this.positions, id0, this.grads, 0, s * w0); 141 | vecAdd(this.positions, id1, this.grads, 0, -s * w1); 142 | } 143 | } 144 | 145 | // Calculate and initialize rest lengths of distance constraints 146 | private initializeEdgeLengths() { 147 | for (let i = 0; i < this.edgeLengths.length; i++) { 148 | const id0 = this.edgeIds[2 * i]; 149 | const id1 = this.edgeIds[2 * i + 1]; 150 | this.edgeLengths[i] = Math.sqrt( 151 | vecDistSquared(this.positions, id0, this.positions, id1) 152 | ); 153 | } 154 | } 155 | 156 | // Get edge ids for distance contraints 157 | private getEdgeIds(): Uint16Array { 158 | const edgeIds = []; 159 | const numTris = this.indices.length / 3; 160 | for (let i = 0; i < numTris; i++) { 161 | for (let j = 0; j < 3; j++) { 162 | // This is one edge of a triangle id0 ------- id1 163 | const id0 = this.indices[3 * i + j]; 164 | const id1 = this.indices[3 * i + ((j + 1) % 3)]; 165 | 166 | // add each edge only once 167 | const n = this.neighbors[3 * i + j]; 168 | if (n < 0 || id0 < id1) { 169 | edgeIds.push(id0); 170 | edgeIds.push(id1); 171 | } 172 | } 173 | } 174 | return new Uint16Array(edgeIds); 175 | } 176 | } 177 | 178 | /** 179 | * Bending contraint class in which all bending constraints 180 | * are derived from 181 | */ 182 | abstract class BendingConstraint extends Constraint { 183 | bendingIds: Int32Array; 184 | constructor( 185 | positions: Float32Array, 186 | invMass: Float32Array, 187 | indices: Uint16Array, 188 | neighbors: Float32Array, 189 | compliance: number 190 | ) { 191 | super(positions, invMass, indices, neighbors, compliance); 192 | this.bendingIds = new Int32Array(this.getTriPairIds()); 193 | } 194 | 195 | // Find four points that make up two adjacent triangles 196 | // id2 197 | // / \ 198 | // / \ 199 | // id0 --- id1 200 | // \ / 201 | // \ / 202 | // id3 203 | private getTriPairIds(): number[] { 204 | const numTris = this.indices.length / 3; // Every 3 vertices is a triangle 205 | const triPairIds = []; 206 | for (let i = 0; i < numTris; i++) { 207 | // triangles 208 | for (let j = 0; j < 3; j++) { 209 | // edges 210 | 211 | // This is one edge of a triangle id0 ------- id1 212 | const id0 = this.indices[3 * i + j]; 213 | const id1 = this.indices[3 * i + ((j + 1) % 3)]; 214 | 215 | // Check to see if there is a neighbor triangle 216 | // See findTriNeighbors for details 217 | const n = this.neighbors[3 * i + j]; 218 | 219 | // Neighbor found! 220 | if (n >= 0) { 221 | // Need to find opposite particle ids that are on opposite sides of shared edge 222 | 223 | // Find the last vertice in this triangle 224 | // this is the vertice of the triangle not on the shared edge. 225 | const id2 = this.indices[3 * i + ((j + 2) % 3)]; 226 | 227 | // Neighbor triangle (using n, since that's the shared edge of the neighbor triangle) 228 | const ni = Math.floor(n / 3); // The neighbot triangle 229 | const nj = n % 3; // LOCAL edge, of the neighbor triangle. (so either 0, 1, 2) 230 | 231 | // Similar to above, find the non-shared vertice 232 | const id3 = this.indices[3 * ni + ((nj + 2) % 3)]; 233 | 234 | triPairIds.push(id0); 235 | triPairIds.push(id1); 236 | triPairIds.push(id2); 237 | triPairIds.push(id3); 238 | } 239 | } 240 | } 241 | return triPairIds; 242 | } 243 | } 244 | 245 | /** 246 | * Performant bending constraint as defined in 247 | * https://matthias-research.github.io/pages/tenMinutePhysics/14-cloth.pdf 248 | */ 249 | export class PerformantBendingConstraint extends BendingConstraint { 250 | bendingLengths: Float32Array; 251 | constructor( 252 | positions: Float32Array, 253 | invMass: Float32Array, 254 | indices: Uint16Array, 255 | neighbors: Float32Array, 256 | compliance: number 257 | ) { 258 | super(positions, invMass, indices, neighbors, compliance); 259 | 260 | this.bendingLengths = new Float32Array(this.bendingIds.length / 4); 261 | this.initBendingLengths(); 262 | } 263 | // Solve bending constraint (which is really just a distance constraint) 264 | // between two unshared vertices in configuration of two adjacent triangles. 265 | // So in this diagram, it would be vertices id2 and id3. 266 | // id2 267 | // / \ 268 | // / \ 269 | // id0 --- id1 270 | // \ / 271 | // \ / 272 | // id3 273 | solve(dt: number) { 274 | const alpha = this.compliance / dt / dt; 275 | 276 | for (let i = 0; i < this.bendingLengths.length; i++) { 277 | const id2 = this.bendingIds[4 * i + 2]; 278 | const id3 = this.bendingIds[4 * i + 3]; 279 | 280 | const w0 = this.invMass[id2]; 281 | const w1 = this.invMass[id3]; 282 | 283 | const w = w0 + w1; 284 | if (w == 0.0) continue; 285 | 286 | vecSetDiff(this.grads, 0, this.positions, id2, this.positions, id3); 287 | const len = Math.sqrt(vecLengthSquared(this.grads, 0)); 288 | 289 | if (len == 0.0) continue; 290 | vecScale(this.grads, 0, 1.0 / len); 291 | const restLen = this.bendingLengths[i]; 292 | const C = len - restLen; 293 | 294 | const s = -C / (w + alpha); 295 | 296 | vecAdd(this.positions, id2, this.grads, 0, s * w0); 297 | vecAdd(this.positions, id3, this.grads, 0, -s * w1); 298 | } 299 | } 300 | private initBendingLengths() { 301 | // Calculate and initialize rest lengths of bending constraints 302 | for (let i = 0; i < this.bendingLengths.length; i++) { 303 | // we know id2 and id3 in bendingIds are the vertices that we want 304 | // to add distance constraints 305 | // see getTriPairIds for details 306 | const id0 = this.bendingIds[4 * i + 2]; 307 | const id1 = this.bendingIds[4 * i + 3]; 308 | this.bendingLengths[i] = Math.sqrt( 309 | vecDistSquared(this.positions, id0, this.positions, id1) 310 | ); 311 | } 312 | } 313 | } 314 | 315 | /** 316 | * Isometric bending constraint as defined in http://mmacklin.com/2017-EG-CourseNotes.pdf 317 | */ 318 | export class IsometricBendingConstraint extends BendingConstraint { 319 | Q: Float32Array; 320 | constructor( 321 | positions: Float32Array, 322 | invMass: Float32Array, 323 | indices: Uint16Array, 324 | neighbors: Float32Array, 325 | compliance: number 326 | ) { 327 | super(positions, invMass, indices, neighbors, compliance); 328 | this.Q = new Float32Array((16 * this.bendingIds.length) / 4); 329 | this.initQ(); 330 | } 331 | 332 | solve(dt: number) { 333 | const alpha = this.compliance / dt / dt; 334 | const memo = new Float32Array(16); 335 | for (let i = 0; i < this.bendingIds.length / 4; i++) { 336 | let idx = i * 4; 337 | const ids = [ 338 | this.bendingIds[idx++], 339 | this.bendingIds[idx++], 340 | this.bendingIds[idx++], 341 | this.bendingIds[idx], 342 | ]; 343 | 344 | const qIdx = i * 16; 345 | 346 | memo[0] = vecDot(this.positions, ids[0], this.positions, ids[0]); 347 | memo[1] = vecDot(this.positions, ids[0], this.positions, ids[1]); 348 | memo[2] = vecDot(this.positions, ids[0], this.positions, ids[2]); 349 | memo[3] = vecDot(this.positions, ids[0], this.positions, ids[3]); 350 | 351 | memo[4] = memo[1]; 352 | memo[5] = vecDot(this.positions, ids[1], this.positions, ids[1]); 353 | memo[6] = vecDot(this.positions, ids[1], this.positions, ids[2]); 354 | memo[7] = vecDot(this.positions, ids[1], this.positions, ids[3]); 355 | 356 | memo[8] = memo[2]; 357 | memo[9] = memo[6]; 358 | memo[10] = vecDot(this.positions, ids[2], this.positions, ids[2]); 359 | memo[11] = vecDot(this.positions, ids[2], this.positions, ids[3]); 360 | 361 | memo[12] = memo[3]; 362 | memo[13] = memo[7]; 363 | memo[14] = memo[11]; 364 | memo[15] = vecDot(this.positions, ids[3], this.positions, ids[3]); 365 | 366 | let C = 0; 367 | { 368 | for (let j = 0; j < 16; j++) { 369 | const Q = this.Q[qIdx + j]; 370 | if (Q === 0.0) continue; 371 | C += Q * memo[j]; 372 | } 373 | } 374 | 375 | // If zero, let's move on. 376 | if (C === 0.0) continue; 377 | 378 | // Calculate grad 379 | { 380 | for (let j = 0; j < 4; j++) { 381 | vecSetZero(this.grads, j); 382 | } 383 | for (let j = 0; j < 16; j++) { 384 | const Q = this.Q[qIdx + j]; 385 | if (Q === 0.0) continue; 386 | vecAdd(this.grads, (j / 4) << 0, this.positions, ids[j % 4], Q); 387 | } 388 | } 389 | 390 | let sum = 0; 391 | for (let j = 0; j < 4; j++) { 392 | if (this.invMass[ids[j]] === 0.0) continue; 393 | sum += this.invMass[ids[j]] * vecDot(this.grads, j, this.grads, j); 394 | } 395 | 396 | const deltaLagrangianMultiplier = -(0.5 * C) / (sum + alpha); 397 | for (let j = 0; j < 4; j++) { 398 | if (this.invMass[ids[j]] === 0.0) continue; 399 | vecAdd( 400 | this.positions, 401 | ids[j], 402 | this.grads, 403 | j, 404 | this.invMass[ids[j]] * deltaLagrangianMultiplier 405 | ); 406 | } 407 | } 408 | } 409 | 410 | private initQ() { 411 | for (let i = 0; i < this.bendingIds.length / 4; i++) { 412 | const ids = [ 413 | this.bendingIds[4 * i], 414 | this.bendingIds[4 * i + 1], 415 | this.bendingIds[4 * i + 2], 416 | this.bendingIds[4 * i + 3], 417 | ]; 418 | 419 | const particles = ids.map((id) => { 420 | const copy = new Float32Array(4); 421 | vecCopy(copy, 0, this.positions, id); 422 | 423 | return copy; 424 | }); 425 | 426 | const cotTheta = (a: DataArray, b: DataArray) => { 427 | const cosTheta = vecDot(a, 0, b, 0); 428 | const cross = new Float32Array(3); 429 | 430 | vecSetCross(cross, 0, a, 0, b, 0); 431 | const sinTheta = vecNorm(cross); 432 | return cosTheta / sinTheta; 433 | }; 434 | 435 | const [p0, p1, p2, p3] = particles; 436 | 437 | const e0 = new Float32Array(3), 438 | e1 = new Float32Array(3), 439 | e2 = new Float32Array(3), 440 | e3 = new Float32Array(3), 441 | e4 = new Float32Array(3), 442 | ne1 = new Float32Array(3), 443 | ne2 = new Float32Array(3), 444 | e01Cross = new Float32Array(3), 445 | e03Cross = new Float32Array(3); 446 | 447 | vecSetDiff(e0, 0, p1, 0, p0, 0); 448 | vecSetDiff(e1, 0, p2, 0, p1, 0); 449 | vecSetDiff(e2, 0, p0, 0, p2, 0); 450 | vecSetDiff(e3, 0, p3, 0, p0, 0); 451 | vecSetDiff(e4, 0, p1, 0, p3, 0); 452 | 453 | vecCopy(ne1, 0, e1, 0); 454 | vecCopy(ne2, 0, e2, 0); 455 | vecScale(ne1, 0, -1); 456 | vecScale(ne2, 0, -1); 457 | 458 | vecSetCross(e01Cross, 0, e0, 0, e1, 0); 459 | vecSetCross(e03Cross, 0, e0, 0, e3, 0); 460 | 461 | const cot01 = cotTheta(e0, ne1); 462 | const cot02 = cotTheta(e0, ne2); 463 | const cot03 = cotTheta(e0, e3); 464 | const cot04 = cotTheta(e0, e4); 465 | 466 | const K = new Float32Array([ 467 | cot01 + cot04, 468 | cot02 + cot03, 469 | -cot01 - cot02, 470 | -cot03 - cot04, 471 | ]); 472 | 473 | const Km: number[][] = multiply4dColumnVectorByTranspose(K); 474 | 475 | const Q = mat4.fromValues( 476 | Km[0][0], 477 | Km[0][1], 478 | Km[0][2], 479 | Km[0][3], 480 | Km[1][0], 481 | Km[1][1], 482 | Km[1][2], 483 | Km[1][3], 484 | Km[2][0], 485 | Km[2][1], 486 | Km[2][2], 487 | Km[2][3], 488 | Km[3][0], 489 | Km[3][1], 490 | Km[3][2], 491 | Km[3][3] 492 | ); 493 | 494 | const A0 = 0.5 * vecNorm(e01Cross); 495 | const A1 = 0.5 * vecNorm(e03Cross); 496 | 497 | mat4.multiplyScalar(Q, Q, 3.0 / (A0 + A1)); 498 | let j = 0; 499 | const qPart = i * 16; 500 | while (j < 16) { 501 | this.Q[qPart + j] = Q[j]; 502 | j++; 503 | } 504 | } 505 | } 506 | } 507 | -------------------------------------------------------------------------------- /src/GPUBufferFactory.ts: -------------------------------------------------------------------------------- 1 | import { Mesh, MeshGPUBuffer, VertexBuffers } from "./types"; 2 | 3 | /** 4 | * Utility class to create GPU buffers 5 | */ 6 | export default class GPUBufferFactory { 7 | private device: GPUDevice; 8 | constructor(device: GPUDevice) { 9 | this.device = device; 10 | } 11 | 12 | createMeshBuffer( 13 | arr: Uint16Array | Float32Array, 14 | usage: GPUBufferUsageFlags 15 | ): MeshGPUBuffer { 16 | const buffer = this.device.createBuffer({ 17 | size: arr.byteLength, 18 | usage: usage | GPUBufferUsage.COPY_DST, 19 | mappedAtCreation: true, 20 | }); 21 | 22 | switch (true) { 23 | case arr instanceof Uint16Array: { 24 | const writeArray = new Uint16Array(buffer.getMappedRange()); 25 | writeArray.set(arr); 26 | break; 27 | } 28 | case arr instanceof Float32Array: { 29 | const writeArray = new Float32Array(buffer.getMappedRange()); 30 | writeArray.set(arr); 31 | break; 32 | } 33 | } 34 | 35 | buffer.unmap(); 36 | return { 37 | data: buffer, 38 | length: arr.length, 39 | }; 40 | } 41 | 42 | createMeshBuffers(mesh: Mesh): VertexBuffers { 43 | const { indices, positions, normals, uvs } = mesh; 44 | 45 | const positionBuffer = this.createMeshBuffer( 46 | positions, 47 | GPUBufferUsage.VERTEX 48 | ); 49 | const indexBuffer = this.createMeshBuffer(indices, GPUBufferUsage.INDEX); 50 | const normalBuffer = this.createMeshBuffer(normals, GPUBufferUsage.VERTEX); 51 | const uvBuffer = this.createMeshBuffer(uvs, GPUBufferUsage.VERTEX); 52 | 53 | return { 54 | indices: indexBuffer, 55 | normals: normalBuffer, 56 | position: positionBuffer, 57 | uvs: uvBuffer, 58 | }; 59 | } 60 | 61 | createUniformBuffer(size: number) { 62 | return this.device.createBuffer({ 63 | size, 64 | usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, 65 | }); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Hash.ts: -------------------------------------------------------------------------------- 1 | import { vecDistSquared } from "./math"; 2 | 3 | /** 4 | * Hash table for self collisions of the Cloth object 5 | * 6 | * https://github.com/matthias-research/pages/blob/master/tenMinutePhysics/11-hashing.pdf 7 | * https://www.carmencincotti.com 8 | */ 9 | export class Hash { 10 | private spacing: number; 11 | private maxNumObjects: number; 12 | private tableSize: number; 13 | private cellCount: Int32Array; 14 | private particleMap: Int32Array; 15 | private queryIds: Int32Array; 16 | private querySize: number; 17 | firstAdjId: Int32Array; 18 | adjIds: Int32Array; 19 | 20 | constructor(spacing: number, maxNumObjects: number) { 21 | this.spacing = spacing; 22 | this.tableSize = 5 * maxNumObjects; 23 | 24 | // Here, cellCount means where to start looking in particleMap 25 | // Add +1 for guard (see in code) 26 | this.cellCount = new Int32Array(this.tableSize + 1); 27 | 28 | // Here, particleMap are the indices of the particles in entire particle list 29 | this.particleMap = new Int32Array(maxNumObjects); // Particle lookup array 30 | this.queryIds = new Int32Array(maxNumObjects); 31 | this.querySize = 0; 32 | 33 | this.maxNumObjects = maxNumObjects; 34 | 35 | // Keep track of where to first index into adjIds 36 | // so firstAdjId[id] = idx for adjIds 37 | this.firstAdjId = new Int32Array(maxNumObjects + 1); 38 | 39 | // All particle ids adjacent to a particular id packed into a dense array. 40 | // Use firstAdjId[id] to access. 41 | this.adjIds = new Int32Array(10 * maxNumObjects); 42 | } 43 | 44 | getAdjacentParticles(id: number) { 45 | const start = this.firstAdjId[id]; 46 | const end = this.firstAdjId[id + 1]; 47 | 48 | return this.adjIds.slice(start, end); 49 | } 50 | 51 | hashCoords(xi: number, yi: number, zi: number) { 52 | const h = (xi * 92837111) ^ (yi * 689287499) ^ (zi * 283923481); // fantasy function 53 | return Math.abs(h) % this.tableSize; 54 | } 55 | 56 | intCoord(coord: number) { 57 | return Math.floor(coord / this.spacing); 58 | } 59 | 60 | hashPos(pos: Float32Array, nr: number) { 61 | return this.hashCoords( 62 | this.intCoord(pos[3 * nr]), 63 | this.intCoord(pos[3 * nr + 1]), 64 | this.intCoord(pos[3 * nr + 2]) 65 | ); 66 | } 67 | 68 | /** 69 | * Create the spatial hash table data structure - based off of 70 | * https://github.com/matthias-research/pages/blob/master/tenMinutePhysics/11-hashing.pdf 71 | * 72 | * Theory: 73 | * https://www.carmencincotti.com/2022-10-31/spatial-hash-maps-part-one/ 74 | * 75 | * Scroll down to Creating the Data Structure Slide 76 | */ 77 | create(pos: Float32Array) { 78 | const numObjects = Math.min(pos.length / 3, this.particleMap.length); 79 | 80 | // Init arrays with 0. Our job is to fill these in. 81 | this.cellCount.fill(0); 82 | this.particleMap.fill(0); 83 | 84 | // Step 1: Count 85 | // Hash and iterate integer at index in arraycellCount 86 | for (let i = 0; i < numObjects; i++) { 87 | const h = this.hashPos(pos, i); 88 | this.cellCount[h]++; 89 | } 90 | 91 | // Step 2: Partial sums 92 | // Mutate cellCount array to contain partial sum of all elements before current index 93 | let start = 0; 94 | for (let i = 0; i < this.tableSize; i++) { 95 | start += this.cellCount[i]; 96 | this.cellCount[i] = start; 97 | } 98 | this.cellCount[this.tableSize] = start; // guard by adding an additional element at the end 99 | 100 | // Step 3: Fill in objects ids 101 | // Now finally fill in the particle array, particleMap 102 | for (let i = 0; i < numObjects; i++) { 103 | const h = this.hashPos(pos, i); 104 | this.cellCount[h]--; 105 | this.particleMap[this.cellCount[h]] = i; 106 | } 107 | } 108 | 109 | /** 110 | * Query for items in hash table 111 | * After execution, check results in: 112 | * - queryIds - particle ids found in query 113 | * - querySize - number of particles found 114 | * 115 | * Theory: 116 | * https://www.carmencincotti.com/2022-11-07/spatial-hash-maps-part-two/ 117 | */ 118 | query(pos: Float32Array, nr: number, maxDist: number) { 119 | const x0 = this.intCoord(pos[3 * nr] - maxDist); 120 | const y0 = this.intCoord(pos[3 * nr + 1] - maxDist); 121 | const z0 = this.intCoord(pos[3 * nr + 2] - maxDist); 122 | 123 | const x1 = this.intCoord(pos[3 * nr] + maxDist); 124 | const y1 = this.intCoord(pos[3 * nr + 1] + maxDist); 125 | const z1 = this.intCoord(pos[3 * nr + 2] + maxDist); 126 | 127 | this.querySize = 0; 128 | 129 | for (let xi = x0; xi <= x1; xi++) { 130 | for (let yi = y0; yi <= y1; yi++) { 131 | for (let zi = z0; zi <= z1; zi++) { 132 | const h = this.hashCoords(xi, yi, zi); 133 | 134 | // Looking for a difference between two, like in slides 135 | const start = this.cellCount[h]; 136 | const end = this.cellCount[h + 1]; 137 | 138 | // If there is a difference, this cell has particles ! 139 | // Save to queryIds 140 | for (let i = start; i < end; i++) { 141 | this.queryIds[this.querySize] = this.particleMap[i]; 142 | this.querySize++; 143 | } 144 | } 145 | } 146 | } 147 | } 148 | 149 | /** 150 | * queryAll is responsible for looping through all particles, calling query() for each, and storing/updating 151 | * the adjacent particles lists. 152 | * 153 | * Theory: 154 | * https://www.carmencincotti.com/2022-11-07/spatial-hash-maps-part-two/ 155 | */ 156 | queryAll(pos: Float32Array, maxDist: number) { 157 | // Keep track of all adjacent id's by indexing into 158 | // this.adjIds 159 | let idx = 0; 160 | 161 | // We only need this number to compare with dist2 162 | // We do not use square root to save ourselves 163 | // from the expensive calculation. 164 | const maxDist2 = maxDist * maxDist; 165 | 166 | for (let i = 0; i < this.maxNumObjects; i++) { 167 | const id0 = i; 168 | this.firstAdjId[id0] = idx; 169 | 170 | // Query for all particles within maxDist from this particle 171 | this.query(pos, id0, maxDist); 172 | 173 | // If particles found in query, register them in adjIds 174 | for (let j = 0; j < this.querySize; j++) { 175 | const id1 = this.queryIds[j]; 176 | 177 | // Skip if id1 > id0, to ensure we only execute the following code once 178 | // Skip if id1 == id0 since a particle can't be adjacent to itself 179 | if (id1 >= id0) continue; 180 | 181 | // Calculate distance-squared between two particles 182 | // We do not use square root to save ourselves 183 | // from the expensive calculation. We just want 184 | // to compare with maxDist2 185 | const dist2 = vecDistSquared(pos, id0, pos, id1); 186 | 187 | if (dist2 > maxDist2) continue; 188 | 189 | // Because each particle can have n adjacencies, 190 | // we need to make sure we are ready to grow the array at a moments notice 191 | // Since we're saving all adjacencies in a single dense array 192 | if (idx >= this.adjIds.length) { 193 | const newIds = new Int32Array(2 * idx); // dynamic array 194 | newIds.set(this.adjIds); 195 | this.adjIds = newIds; 196 | } 197 | this.adjIds[idx++] = id1; 198 | } 199 | } 200 | 201 | // Manually set the last extra space with current idx 202 | this.firstAdjId[this.maxNumObjects] = idx; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/ObjLoader.ts: -------------------------------------------------------------------------------- 1 | import { Mesh } from "./types"; 2 | 3 | type ObjFile = string; 4 | type FilePath = string; 5 | 6 | type CacheVertice = number; 7 | type CacheFace = string; 8 | type CacheNormal = number; 9 | type CacheUv = number; 10 | type CacheArray = T[][]; 11 | 12 | type toBeFloat32 = number; 13 | type toBeUInt16 = number; 14 | 15 | /** 16 | * ObjLoader to load in .obj files. This has only been tested on Blender .obj exports that have been UV unwrapped 17 | * and you may need to throw out certain returned fields if the .OBJ is missing them (ie. uvs or normals) 18 | * 19 | * Use at your own risk. 20 | * 21 | * TODO:// Draco ? https://github.com/google/draco 22 | */ 23 | export default class ObjLoader { 24 | constructor() {} 25 | async load(filePath: FilePath): Promise { 26 | const resp = await fetch(filePath); 27 | if (!resp.ok) { 28 | throw new Error( 29 | `ObjLoader could not fine file at ${filePath}. Please check your path.` 30 | ); 31 | } 32 | const file = await resp.text(); 33 | 34 | if (file.length === 0) { 35 | throw new Error(`${filePath} File is empty.`); 36 | } 37 | 38 | return file; 39 | } 40 | 41 | /** 42 | * Parse a given obj file into a Mesh 43 | */ 44 | parse(file: ObjFile): Mesh { 45 | const lines = file?.split("\n"); 46 | 47 | // Store what's in the object file here 48 | const cachedVertices: CacheArray = []; 49 | const cachedFaces: CacheArray = []; 50 | const cachedNormals: CacheArray = []; 51 | const cachedUvs: CacheArray = []; 52 | 53 | // Read out data from file and store into appropriate source buckets 54 | { 55 | for (const untrimmedLine of lines) { 56 | const line = untrimmedLine.trim(); // remove whitespace 57 | const [startingChar, ...data] = line.split(" "); 58 | switch (startingChar) { 59 | case "v": 60 | cachedVertices.push(data.map(parseFloat)); 61 | break; 62 | case "vt": 63 | cachedUvs.push(data.map(Number)); 64 | break; 65 | case "vn": 66 | cachedNormals.push(data.map(parseFloat)); 67 | break; 68 | case "f": 69 | cachedFaces.push(data); 70 | break; 71 | } 72 | } 73 | } 74 | 75 | // Use these intermediate arrays to leverage Array API (.push) 76 | const finalPosition: toBeFloat32[] = []; 77 | const finalNormals: toBeFloat32[] = []; 78 | const finalUvs: toBeFloat32[] = []; 79 | const finalIndices: toBeUInt16[] = []; 80 | 81 | // Loop through faces, and return the buffers that will be sent to GPU for rendering 82 | { 83 | const cache: Record = {}; 84 | let i = 0; 85 | for (const faces of cachedFaces) { 86 | for (const faceString of faces) { 87 | // If we already saw this, add to indices list. 88 | if (cache[faceString] !== undefined) { 89 | finalIndices.push(cache[faceString]); 90 | continue; 91 | } 92 | 93 | cache[faceString] = i; 94 | finalIndices.push(i); 95 | 96 | // Need to convert strings to integers, and subtract by 1 to get to zero index. 97 | const [vI, uvI, nI] = faceString 98 | .split("/") 99 | .map((s: string) => Number(s) - 1); 100 | 101 | vI > -1 && finalPosition.push(...cachedVertices[vI]); 102 | uvI > -1 && finalUvs.push(...cachedUvs[uvI]); 103 | nI > -1 && finalNormals.push(...cachedNormals[nI]); 104 | 105 | i += 1; 106 | } 107 | } 108 | } 109 | 110 | return { 111 | positions: new Float32Array(finalPosition), 112 | uvs: new Float32Array(finalUvs), 113 | normals: new Float32Array(finalNormals), 114 | indices: new Uint16Array(finalIndices), 115 | }; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/PerspectiveCamera.ts: -------------------------------------------------------------------------------- 1 | import { mat4, quat, vec3 } from "gl-matrix"; 2 | import Transformation from "./Transformation"; 3 | import { ProjectionMatrix, TransformationMatrix, ViewMatrix } from "./types"; 4 | 5 | /** 6 | * Scene Perspective Camera class 7 | */ 8 | export default class PerspectiveCamera extends Transformation { 9 | readonly projectionMatrix: ProjectionMatrix; 10 | constructor(fov: number, aspectRatio: number, near: number, far: number) { 11 | super(); 12 | 13 | // Assume perspective always 14 | this.projectionMatrix = mat4.create(); 15 | mat4.perspective(this.projectionMatrix, fov, aspectRatio, near, far); 16 | } 17 | 18 | get viewMatrix(): ViewMatrix { 19 | const intermediaryMatrix = mat4.create(); 20 | const intermediaryQuaternion = quat.create(); 21 | 22 | // Inverse the rotation 23 | const rotationComponent = mat4.getRotation( 24 | intermediaryQuaternion, 25 | this.modelMatrix 26 | ); 27 | mat4.fromQuat(intermediaryMatrix, rotationComponent); 28 | mat4.transpose(intermediaryMatrix, intermediaryMatrix); 29 | 30 | // Inverse the translation component 31 | const translationComponent = vec3.create(); 32 | mat4.getTranslation(translationComponent, this.modelMatrix); 33 | vec3.negate(translationComponent, translationComponent); 34 | mat4.translate( 35 | intermediaryMatrix, 36 | intermediaryMatrix, 37 | translationComponent 38 | ); 39 | 40 | return intermediaryMatrix; 41 | } 42 | 43 | get projectionViewMatrix(): TransformationMatrix { 44 | const projectionViewMatrix = mat4.create(); 45 | mat4.multiply(projectionViewMatrix, this.projectionMatrix, this.viewMatrix); 46 | 47 | return projectionViewMatrix; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/PhysicsObject.ts: -------------------------------------------------------------------------------- 1 | import ClothSelfCollision, { Collision } from "./Collison"; 2 | import { Constraint, ConstraintFactory } from "./Constraint"; 3 | import { Hash } from "./Hash"; 4 | import { 5 | vecAdd, 6 | vecCopy, 7 | vecLengthSquared, 8 | vecScale, 9 | vecSetCross, 10 | vecSetDiff, 11 | vecSetZero, 12 | } from "./math"; 13 | import { Mesh } from "./types"; 14 | 15 | /** 16 | * Abstract class that all meshes should inherit from to use XPBD physics 17 | */ 18 | export default abstract class PhysicsObject { 19 | numParticles: number; 20 | positions: Float32Array; 21 | prevPositions: Float32Array; 22 | vels: Float32Array; 23 | invMass: Float32Array; 24 | normals: Float32Array; 25 | indices: Uint16Array; 26 | neighbors: Float32Array; 27 | constraints: Constraint[]; 28 | constraintFactory: ConstraintFactory; 29 | collisions: Collision[]; 30 | 31 | constructor(mesh: Mesh) { 32 | this.numParticles = mesh.positions.length / 3; 33 | this.positions = new Float32Array(mesh.positions); 34 | this.normals = new Float32Array(mesh.normals); 35 | this.prevPositions = new Float32Array(mesh.positions); 36 | this.vels = new Float32Array(3 * this.numParticles); 37 | this.invMass = new Float32Array(this.numParticles); 38 | this.indices = new Uint16Array(mesh.indices); 39 | this.constraints = []; 40 | this.collisions = []; 41 | 42 | this.invMass = this.initInvMass(); 43 | this.neighbors = this.findTriNeighbors(); 44 | 45 | this.constraintFactory = new ConstraintFactory( 46 | this.positions, 47 | this.invMass, 48 | this.indices, 49 | this.neighbors 50 | ); 51 | } 52 | 53 | solve(dt: number) { 54 | for (let i = 0; i < this.numParticles; i++) { 55 | // Floor collision ( we currently don't have a need for it) 56 | let y = this.positions[3 * i + 1]; 57 | const height = -0.7; 58 | if (y < height) { 59 | vecCopy(this.positions, i, this.prevPositions, i); 60 | this.positions[3 * i + 1] = height; 61 | } 62 | } 63 | for (const constraint of this.constraints) { 64 | constraint.solve(dt); 65 | } 66 | 67 | for (const collision of this.collisions) { 68 | collision.solve(dt); 69 | } 70 | } 71 | 72 | preSolve(dt: number, gravity: Float32Array) { 73 | for (let i = 0; i < this.numParticles; i++) { 74 | if (this.invMass[i] == 0.0) continue; 75 | vecAdd(this.vels, i, gravity, 0, dt); 76 | const v = Math.sqrt(vecLengthSquared(this.vels, i)); 77 | const maxV = 0.2 * (0.01 / dt); 78 | if (v > maxV) { 79 | vecScale(this.vels, i, maxV / v); 80 | } 81 | vecCopy(this.prevPositions, i, this.positions, i); 82 | vecAdd(this.positions, i, this.vels, i, dt); 83 | } 84 | } 85 | postSolve(dt: number) { 86 | for (let i = 0; i < this.numParticles; i++) { 87 | if (this.invMass[i] == 0.0) continue; 88 | vecSetDiff( 89 | this.vels, 90 | i, 91 | this.positions, 92 | i, 93 | this.prevPositions, 94 | i, 95 | 1.0 / dt 96 | ); 97 | } 98 | } 99 | updateVertexNormals() { 100 | for (let i = 0; i < this.numParticles; i++) { 101 | vecSetZero(this.normals, i); 102 | } 103 | for (let i = 0; i < this.numParticles; i++) { 104 | const id0 = this.indices[3 * i]; 105 | const id1 = this.indices[3 * i + 1]; 106 | const id2 = this.indices[3 * i + 2]; 107 | 108 | const e0 = [0, 0, 0]; 109 | const e1 = [0, 0, 0]; 110 | const c = [0, 0, 0]; 111 | 112 | // Find Area of Triangle 113 | // Calculate edge vectors from id0 114 | vecSetDiff(e0, 0, this.positions, id1, this.positions, id0); 115 | vecSetDiff(e1, 0, this.positions, id2, this.positions, id0); 116 | 117 | // Area of triangle 1/2 |AB x AC| 118 | vecSetCross(c, 0, e0, 0, e1, 0); 119 | 120 | vecAdd(this.normals, id0, c, 0, 0.333); 121 | vecAdd(this.normals, id1, c, 0, 0.333); 122 | vecAdd(this.normals, id2, c, 0, 0.333); 123 | } 124 | } 125 | 126 | private initInvMass(): Float32Array { 127 | const invMass = new Float32Array(this.numParticles); 128 | const numTris = this.indices.length / 3; 129 | const e0 = [0.0, 0.0, 0.0]; // edge 0 vector 130 | const e1 = [0.0, 0.0, 0.0]; // edge 1 vector 131 | const c = [0.0, 0.0, 0.0]; // cross vector of e0 x e1 132 | 133 | for (let i = 0; i < numTris; i++) { 134 | const id0 = this.indices[3 * i]; 135 | const id1 = this.indices[3 * i + 1]; 136 | const id2 = this.indices[3 * i + 2]; 137 | 138 | // Find Area of Triangle 139 | // Calculate edge vectors from id0 140 | vecSetDiff(e0, 0, this.positions, id1, this.positions, id0); 141 | vecSetDiff(e1, 0, this.positions, id2, this.positions, id0); 142 | 143 | // Area of triangle 1/2 |AB x AC| 144 | vecSetCross(c, 0, e0, 0, e1, 0); 145 | const A = 0.5 * Math.sqrt(vecLengthSquared(c, 0)); // magnitude of cross vector 146 | 147 | // Divide mass among 3 points in triangle 148 | const pInvMass = A > 0.0 ? 1.0 / A / 3.0 : 0.0; 149 | 150 | // Add since vertices may be shared 151 | invMass[id0] += pInvMass; 152 | invMass[id1] += pInvMass; 153 | invMass[id2] += pInvMass; 154 | } 155 | 156 | return invMass; 157 | } 158 | 159 | private findTriNeighbors(): Float32Array { 160 | const edges = []; 161 | const numTris = this.indices.length / 3; 162 | 163 | for (let i = 0; i < numTris; i++) { 164 | for (let j = 0; j < 3; j++) { 165 | const id0 = this.indices[3 * i + j]; 166 | const id1 = this.indices[3 * i + ((j + 1) % 3)]; 167 | edges.push({ 168 | id0: Math.min(id0, id1), // particle 1 169 | id1: Math.max(id0, id1), // particle 2 170 | edgeNr: 3 * i + j, // global edge number 171 | }); 172 | } 173 | } 174 | // sort so common edges are next to each other 175 | edges.sort((a, b) => 176 | a.id0 < b.id0 || (a.id0 == b.id0 && a.id1 < b.id1) ? -1 : 1 177 | ); 178 | 179 | // find matching edges 180 | const neighbors = new Float32Array(3 * numTris); 181 | neighbors.fill(-1); // -1 means open edge, as in no neighbors 182 | 183 | let i = 0; 184 | while (i < edges.length) { 185 | const e0 = edges[i]; 186 | const e1 = edges[i + 1]; 187 | 188 | // If the particles share the same edge, update the neighbors list 189 | // with their neighbors corresponding global edge number 190 | if (e0.id0 === e1.id0 && e0.id1 === e1.id1) { 191 | neighbors[e0.edgeNr] = e1.edgeNr; 192 | neighbors[e1.edgeNr] = e0.edgeNr; 193 | } 194 | i += 2; 195 | } 196 | 197 | return neighbors; 198 | } 199 | } 200 | 201 | export class ClothPhysicsObject extends PhysicsObject { 202 | thickness: number; 203 | hash: Hash; 204 | constructor(mesh: Mesh, thickness: number) { 205 | super(mesh); 206 | this.thickness = thickness; 207 | 208 | // Spacing calculated by looking into the obj file and seeing the length between two particles. 209 | const spacing = thickness; 210 | this.hash = new Hash(spacing, this.numParticles); 211 | } 212 | 213 | preIntegration(dt: number) { 214 | this.hash.create(this.positions); 215 | this.hash.queryAll(this.positions, ((1 / 60) * 0.2 * this.thickness) / dt); 216 | } 217 | /** 218 | * Adds a DistanceConstraint to the Cloth physics object 219 | * @param compliance 220 | */ 221 | public registerDistanceConstraint(compliance: number) { 222 | this.constraints.push( 223 | this.constraintFactory.createDistanceConstraint(compliance) 224 | ); 225 | } 226 | 227 | /** 228 | * Adds a PerformantBendingConstraint to the Cloth physics object 229 | * @param compliance 230 | */ 231 | public registerPerformantBendingConstraint(compliance: number) { 232 | this.constraints.push( 233 | this.constraintFactory.createPerformantBendingConstraint(compliance) 234 | ); 235 | } 236 | 237 | /** 238 | * Adds an IsometricBendingConstraint to the Cloth physics object 239 | * @param compliance 240 | */ 241 | public registerIsometricBendingConstraint(compliance: number) { 242 | this.constraints.push( 243 | this.constraintFactory.createIsometricBendingConstraint(compliance) 244 | ); 245 | } 246 | 247 | /** 248 | * Adds a Self Collision constraint to the Cloth physics object 249 | */ 250 | public registerSelfCollision() { 251 | this.collisions.push( 252 | new ClothSelfCollision( 253 | this.positions, 254 | this.prevPositions, 255 | this.invMass, 256 | this.thickness, 257 | this.hash 258 | ) 259 | ); 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /src/Transformation.ts: -------------------------------------------------------------------------------- 1 | import { mat4, vec3 } from "gl-matrix"; 2 | import { ModelMatrix, ViewMatrix } from "./types"; 3 | 4 | /** 5 | * Transformation class that provides helper functions to 6 | * update a model's position, scale, and rotation 7 | */ 8 | export default class Transformation { 9 | private _translation: mat4; 10 | private _rotation: mat4; 11 | private _scale: mat4; 12 | private _modelMatrix: ModelMatrix; 13 | 14 | constructor() { 15 | this._translation = mat4.create(); 16 | this._rotation = mat4.create(); 17 | this._scale = mat4.create(); 18 | this._modelMatrix = mat4.create(); 19 | } 20 | 21 | get position(): vec3 { 22 | const outVector = this.translation; 23 | vec3.transformMat4(outVector, outVector, this._rotation); 24 | 25 | return outVector; 26 | } 27 | 28 | set translation(pos: vec3) { 29 | mat4.fromTranslation(this._translation, pos); 30 | this.refreshModelMatrix(); 31 | } 32 | 33 | get translation(): vec3 { 34 | return vec3.fromValues( 35 | this._translation[12], 36 | this._translation[13], 37 | this._translation[14] 38 | ); 39 | } 40 | 41 | set scale(scale: vec3) { 42 | this._scale[0] = scale[0]; 43 | this._scale[5] = scale[1]; 44 | this._scale[10] = scale[2]; 45 | this.refreshModelMatrix(); 46 | } 47 | 48 | // Rotation with Euler Order XYZ 49 | set rotationXYZ(rot: vec3) { 50 | const intermediaryMatrix = mat4.create(); 51 | mat4.rotateX(intermediaryMatrix, intermediaryMatrix, rot[0]); 52 | mat4.rotateY(intermediaryMatrix, intermediaryMatrix, rot[1]); 53 | mat4.rotateZ(intermediaryMatrix, intermediaryMatrix, rot[2]); 54 | mat4.copy(this._rotation, intermediaryMatrix); 55 | this.refreshModelMatrix(); 56 | } 57 | 58 | get modelMatrix(): ModelMatrix { 59 | return mat4.clone(this._modelMatrix); 60 | } 61 | 62 | set modelMatrix(m: ModelMatrix) { 63 | this._modelMatrix = m; 64 | } 65 | 66 | getModelViewMatrix(viewMatrix: ViewMatrix): ModelMatrix { 67 | const modelViewMatrix = this.modelMatrix; 68 | 69 | mat4.multiply(modelViewMatrix, viewMatrix, modelViewMatrix); 70 | return modelViewMatrix; 71 | } 72 | 73 | getNormalMatrix(viewMatrix: ViewMatrix): ModelMatrix { 74 | const normalMatrix = this.getModelViewMatrix(viewMatrix); 75 | mat4.invert(normalMatrix, normalMatrix); 76 | mat4.transpose(normalMatrix, normalMatrix); 77 | 78 | return normalMatrix; 79 | } 80 | 81 | private refreshModelMatrix() { 82 | mat4.multiply(this._modelMatrix, this._translation, this._scale); 83 | mat4.multiply(this._modelMatrix, this._rotation, this._modelMatrix); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/WebGPUCanvas.ts: -------------------------------------------------------------------------------- 1 | import GPUBufferFactory from "./GPUBufferFactory"; 2 | import { VertexBuffers, RawShaderData, Shader, Mesh } from "./types"; 3 | 4 | type PresentationSize = [number, number]; 5 | 6 | /** 7 | * A WebGPU Canvas class that provides helpers to the underlying WebGPU API. 8 | */ 9 | export default class WebGPUCanvas { 10 | private context: GPUCanvasContext; 11 | private bufferFactory: GPUBufferFactory; 12 | readonly device: GPUDevice; 13 | presentationFormat: GPUTextureFormat; 14 | width: number; 15 | height: number; 16 | private constructor( 17 | context: GPUCanvasContext, 18 | device: GPUDevice, 19 | presentationFormat: GPUTextureFormat, 20 | width: number, 21 | height: number 22 | ) { 23 | this.context = context; 24 | this.device = device; 25 | this.presentationFormat = presentationFormat; 26 | this.width = width; 27 | this.height = height; 28 | this.bufferFactory = new GPUBufferFactory(this.device); 29 | } 30 | static async init(canvasId: string): Promise { 31 | if (!navigator.gpu) { 32 | throw new Error("WebGPU cannot be initialized - navigator.gpu not found"); 33 | } 34 | 35 | const adapter = await navigator.gpu.requestAdapter(); 36 | if (!adapter) { 37 | throw new Error("WebGPU cannot be initialized - Adapter not found"); 38 | } 39 | 40 | const device = await adapter.requestDevice(); 41 | 42 | device.lost.then((e) => { 43 | throw new Error( 44 | `WebGPU cannot be initialized - Device has been lost - ${e.message}` 45 | ); 46 | }); 47 | 48 | const canvas = document.getElementById(canvasId); 49 | if (!canvas || !(canvas instanceof HTMLCanvasElement)) { 50 | throw new Error( 51 | `WebGPU cannot be initialized - Element with id ${canvasId} is not a Canvas Element` 52 | ); 53 | } 54 | const context = canvas.getContext("webgpu"); 55 | if (!context) { 56 | throw new Error( 57 | `WebGPU cannot be initialized - Element with id ${canvasId} does not support WebGPU, does your browser support it?` 58 | ); 59 | } 60 | 61 | const devicePixelRatio = window.devicePixelRatio || 1; 62 | 63 | canvas.width = window.innerWidth * devicePixelRatio; 64 | canvas.height = window.innerHeight * devicePixelRatio; 65 | 66 | // ~~ CONFIGURE THE SWAP CHAIN ~~ 67 | const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); 68 | 69 | context.configure({ 70 | device, 71 | format: presentationFormat, 72 | }); 73 | 74 | return new WebGPUCanvas( 75 | context, 76 | device, 77 | presentationFormat, 78 | canvas.width, 79 | canvas.height 80 | ); 81 | } 82 | 83 | get presentationSize(): PresentationSize { 84 | return [this.width, this.height]; 85 | } 86 | 87 | get aspectRatio(): number { 88 | return this.width / this.height; 89 | } 90 | 91 | createRenderPipeline(shader: Shader) { 92 | return this.device.createRenderPipeline({ 93 | layout: "auto", 94 | depthStencil: { 95 | depthWriteEnabled: true, 96 | depthCompare: "less", 97 | format: "depth24plus", 98 | }, 99 | ...shader, 100 | }); 101 | } 102 | 103 | createUniformBuffer(size: number): GPUBuffer { 104 | return this.bufferFactory.createUniformBuffer(size); 105 | } 106 | 107 | createBindGroup(descriptor: GPUBindGroupDescriptor): GPUBindGroup { 108 | return this.device.createBindGroup(descriptor); 109 | } 110 | 111 | createMeshBuffers(mesh: Mesh): VertexBuffers { 112 | return this.bufferFactory.createMeshBuffers(mesh); 113 | } 114 | 115 | updateUniform(buffer: GPUBuffer, data: Float32Array, offset: number) { 116 | this.device.queue.writeBuffer( 117 | buffer, 118 | offset, 119 | data.buffer, 120 | data.byteOffset, 121 | data.byteLength 122 | ); 123 | } 124 | 125 | createShader(rawShaderData: RawShaderData): Shader { 126 | const shaderModule = this.device.createShaderModule({ 127 | code: rawShaderData.code, 128 | }); 129 | return { 130 | vertex: { 131 | module: shaderModule, 132 | ...rawShaderData.vertex, 133 | }, 134 | fragment: { 135 | module: shaderModule, 136 | targets: [ 137 | { 138 | format: this.presentationFormat, 139 | }, 140 | ], 141 | ...rawShaderData.fragment, 142 | }, 143 | }; 144 | } 145 | 146 | draw(drawCb: (drawHelper: GPURenderPassEncoder) => void) { 147 | const depthTexture = this.device.createTexture({ 148 | size: this.presentationSize, 149 | format: "depth24plus", 150 | usage: GPUTextureUsage.RENDER_ATTACHMENT, 151 | }); 152 | 153 | // ~~ CREATE RENDER PASS DESCRIPTOR ~~ 154 | const renderPassDescriptor: GPURenderPassDescriptor = { 155 | colorAttachments: [ 156 | { 157 | view: this.context.getCurrentTexture().createView(), 158 | clearValue: { r: 0.5294, g: 0.8039, b: 0.9725, a: 1.0 }, 159 | loadOp: "clear", 160 | storeOp: "store", 161 | }, 162 | ], 163 | depthStencilAttachment: { 164 | view: depthTexture.createView(), 165 | depthClearValue: 1.0, 166 | depthLoadOp: "clear", 167 | depthStoreOp: "store", 168 | }, 169 | }; 170 | 171 | // ~~ Define render loop ~~ 172 | const frame = () => { 173 | renderPassDescriptor.colorAttachments[0].view = this.context 174 | .getCurrentTexture() 175 | .createView(); 176 | renderPassDescriptor.depthStencilAttachment.view = 177 | depthTexture.createView(); 178 | const commandEncoder = this.device.createCommandEncoder(); 179 | const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); 180 | drawCb(passEncoder); 181 | passEncoder.end(); 182 | this.device.queue.submit([commandEncoder.finish()]); 183 | requestAnimationFrame(frame); 184 | }; 185 | 186 | requestAnimationFrame(frame); 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /src/app.ts: -------------------------------------------------------------------------------- 1 | import ObjLoader from "./ObjLoader"; 2 | import WebGPUCanvas from "./WebGPUCanvas"; 3 | import Camera from "./PerspectiveCamera"; 4 | import DefaultProgram from "./programs/DefaultProgram"; 5 | import Transformation from "./Transformation"; 6 | import Cloth from "./Cloth"; 7 | 8 | // For the simulation to work with collisions, 9 | // it is wise to use equal spacing between all the particles. 10 | // This is possible to do in Blender even if the cloth as a whole is a rectangle. 11 | const OBJECT_URL: string = "cloth_30_45_l.obj"; 12 | const VERTEX_SPACING = 0.05; 13 | 14 | (async () => { 15 | try { 16 | const objLoader = new ObjLoader(); 17 | const [objFile, gpuCanvas] = await Promise.all([ 18 | objLoader.load(OBJECT_URL), 19 | WebGPUCanvas.init("canvas-container"), 20 | ]); 21 | 22 | // Create mesh data 23 | const mesh = objLoader.parse(objFile); 24 | 25 | const modelTransformation = new Transformation(); 26 | modelTransformation.scale = [1.0, 1.0, 1.0]; 27 | modelTransformation.rotationXYZ = [0, 1, 0]; 28 | 29 | // Create Buffers and Bind Groups 30 | const meshBuffers = gpuCanvas.createMeshBuffers(mesh); 31 | 32 | // Initialize WebGPU program 33 | const program = DefaultProgram.init(gpuCanvas); 34 | program.registerModelMatrices(1); 35 | 36 | // Initalize Scene objects 37 | const lightModel = new Transformation(); 38 | lightModel.translation = [5.0, 0.0, 0.0]; 39 | lightModel.rotationXYZ = [0, 0, 0]; 40 | 41 | const perspectiveCamera = new Camera( 42 | (2 * Math.PI) / 5, 43 | gpuCanvas.aspectRatio, 44 | 0.1, 45 | 100 46 | ); 47 | 48 | perspectiveCamera.translation = [0, 0.0, 2.1]; 49 | 50 | // Create Physics Object 51 | 52 | // thickness and spacing in hash table needed adjusting. 53 | const thickness = VERTEX_SPACING; 54 | const cloth = new Cloth(mesh, thickness); 55 | 56 | // Initialize physics parameters 57 | const dt = 1.0 / 60.0; 58 | const steps = 10; 59 | const sdt = dt / steps; 60 | const gravity = new Float32Array([-1.1, -9.8, 2.5]); 61 | 62 | cloth.registerDistanceConstraint(0.0); 63 | cloth.registerPerformantBendingConstraint(1.0); 64 | cloth.registerSelfCollision(); 65 | // cloth.registerIsometricBendingConstraint(10.0) 66 | 67 | // Start animation loop 68 | gpuCanvas.draw((renderPassAPI) => { 69 | gravity[2] = Math.cos(Date.now() / 2000) * 15.5; 70 | cloth.preIntegration(sdt); 71 | for (let i = 0; i < steps; i++) { 72 | cloth.preSolve(sdt, gravity); 73 | cloth.solve(sdt); 74 | cloth.postSolve(sdt); 75 | } 76 | 77 | cloth.updateVertexNormals(); 78 | 79 | gpuCanvas.device.queue.writeBuffer( 80 | meshBuffers.position.data, 81 | 0, 82 | cloth.positions, 83 | 0, 84 | meshBuffers.position.length 85 | ); 86 | gpuCanvas.device.queue.writeBuffer( 87 | meshBuffers.normals.data, 88 | 0, 89 | cloth.normals, 90 | 0, 91 | meshBuffers.normals.length 92 | ); 93 | program 94 | .activate(renderPassAPI) 95 | .updateCameraUniforms(perspectiveCamera) 96 | .updateModelUniforms( 97 | modelTransformation.modelMatrix, 98 | modelTransformation.getNormalMatrix(perspectiveCamera.viewMatrix), 99 | 0 100 | ) 101 | .updateLightModelPositionUniform(lightModel.position) 102 | .render(renderPassAPI, meshBuffers); 103 | }); 104 | } catch (e) { 105 | const errorContainerEl = document.getElementById("error-text"); 106 | if (errorContainerEl) { 107 | errorContainerEl.innerHTML = e as string; 108 | } 109 | throw e; 110 | } 111 | })(); 112 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGPU Cloth Simulator 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /src/math.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Math utility classes for DataArrays 3 | */ 4 | 5 | export type DataArray = Float32Array | Int32Array | number[]; 6 | 7 | /** 8 | * Zero out 3-element vector within a DataArray 9 | */ 10 | export function vecSetZero(a: DataArray | Array, anr: number) { 11 | anr *= 3; 12 | a[anr++] = 0.0; 13 | a[anr++] = 0.0; 14 | a[anr] = 0.0; 15 | } 16 | 17 | /** 18 | * Scale a 3-element vector within a DataArray 19 | */ 20 | export function vecScale(a: DataArray, anr: number, scale = 1.0) { 21 | anr *= 3; 22 | a[anr++] *= scale; 23 | a[anr++] *= scale; 24 | a[anr] *= scale; 25 | } 26 | 27 | /** 28 | * Copy a 3-element vector within a DataArray 29 | */ 30 | export function vecCopy(a: DataArray, anr: number, b: DataArray, bnr: number) { 31 | anr *= 3; 32 | bnr *= 3; 33 | a[anr++] = b[bnr++]; 34 | a[anr++] = b[bnr++]; 35 | a[anr] = b[bnr]; 36 | } 37 | 38 | /** 39 | * Add two 3-element vectors and mutate the first vector argument 40 | */ 41 | export function vecAdd( 42 | a: DataArray, 43 | anr: number, 44 | b: DataArray, 45 | bnr: number, 46 | scale = 1.0 47 | ) { 48 | anr *= 3; 49 | bnr *= 3; 50 | a[anr++] += b[bnr++] * scale; 51 | a[anr++] += b[bnr++] * scale; 52 | a[anr] += b[bnr] * scale; 53 | } 54 | 55 | /** 56 | * Subtract two 3-element vectors 57 | */ 58 | export function vecSetDiff( 59 | dst: DataArray, 60 | dnr: number, 61 | a: DataArray, 62 | anr: number, 63 | b: DataArray, 64 | bnr: number, 65 | scale = 1.0 66 | ) { 67 | dnr *= 3; 68 | anr *= 3; 69 | bnr *= 3; 70 | dst[dnr++] = (a[anr++] - b[bnr++]) * scale; 71 | dst[dnr++] = (a[anr++] - b[bnr++]) * scale; 72 | dst[dnr] = (a[anr] - b[bnr]) * scale; 73 | } 74 | 75 | /** 76 | * Find the length of a 3-element vector within a DataArray 77 | */ 78 | export function vecLengthSquared(a: DataArray, anr: number): number { 79 | anr *= 3; 80 | let a0 = a[anr], 81 | a1 = a[anr + 1], 82 | a2 = a[anr + 2]; 83 | return a0 * a0 + a1 * a1 + a2 * a2; 84 | } 85 | 86 | /** 87 | * Find the distance between two 3-element vectors within a DataArray 88 | * https://en.wikipedia.org/wiki/Euclidean_distance 89 | */ 90 | export function vecDistSquared( 91 | a: DataArray, 92 | anr: number, 93 | b: DataArray, 94 | bnr: number 95 | ) { 96 | anr *= 3; 97 | bnr *= 3; 98 | let a0 = a[anr] - b[bnr], 99 | a1 = a[anr + 1] - b[bnr + 1], 100 | a2 = a[anr + 2] - b[bnr + 2]; 101 | return a0 * a0 + a1 * a1 + a2 * a2; 102 | } 103 | 104 | /** 105 | * Find the dot product of two 3-element vectors 106 | */ 107 | export function vecDot(a: DataArray, anr: number, b: DataArray, bnr: number) { 108 | anr *= 3; 109 | bnr *= 3; 110 | return a[anr] * b[bnr] + a[anr + 1] * b[bnr + 1] + a[anr + 2] * b[bnr + 2]; 111 | } 112 | 113 | /** 114 | * Find the cross product of two 3-element vectors 115 | */ 116 | export function vecSetCross( 117 | a: DataArray, 118 | anr: number, 119 | b: DataArray, 120 | bnr: number, 121 | c: DataArray, 122 | cnr: number 123 | ) { 124 | anr *= 3; 125 | bnr *= 3; 126 | cnr *= 3; 127 | a[anr++] = b[bnr + 1] * c[cnr + 2] - b[bnr + 2] * c[cnr + 1]; 128 | a[anr++] = b[bnr + 2] * c[cnr + 0] - b[bnr + 0] * c[cnr + 2]; 129 | a[anr] = b[bnr + 0] * c[cnr + 1] - b[bnr + 1] * c[cnr + 0]; 130 | } 131 | 132 | /** 133 | * Find the L2 norm of two vectors 134 | */ 135 | export const vecNorm = (a: DataArray): number => { 136 | return Math.sqrt( 137 | (a as any[]).reduce((prev: number, curr: number) => prev + curr ** 2, 0) 138 | ); 139 | }; 140 | 141 | /** 142 | * Multiply a 4d column vector by its transpose 143 | */ 144 | export function multiply4dColumnVectorByTranspose(a: DataArray): number[][] { 145 | const out: number[][] = [[], [], [], []]; 146 | 147 | for (let i = 0; i < 4; i++) { 148 | for (let j = 0; j < 4; j++) { 149 | out[i][j] = a[i] * a[j]; 150 | } 151 | } 152 | 153 | return out; 154 | } 155 | 156 | export function vecSetSum( 157 | dst: DataArray, 158 | dnr: number, 159 | a: DataArray, 160 | anr: number, 161 | b: DataArray, 162 | bnr: number, 163 | scale = 1.0 164 | ) { 165 | dnr *= 3; 166 | anr *= 3; 167 | bnr *= 3; 168 | dst[dnr++] = (a[anr++] + b[bnr++]) * scale; 169 | dst[dnr++] = (a[anr++] + b[bnr++]) * scale; 170 | dst[dnr] = (a[anr] + b[bnr]) * scale; 171 | } 172 | -------------------------------------------------------------------------------- /src/programs/DebuggerProgram.ts: -------------------------------------------------------------------------------- 1 | import { Pipeline, RenderPassAPI, GPUCanvas, VertexBuffers } from "../types"; 2 | import Program from "./Program"; 3 | import debuggerShaderData from "./shaders/debuggerShader"; 4 | 5 | export default class DebuggerProgram extends Program { 6 | private constructor(gpuCanvas: GPUCanvas, pipeline: Pipeline) { 7 | super(gpuCanvas, pipeline); 8 | } 9 | 10 | static init(gpuCanvas: GPUCanvas) { 11 | const shader = gpuCanvas.createShader(debuggerShaderData); 12 | const pipeline = gpuCanvas.createRenderPipeline(shader); 13 | return new DebuggerProgram(gpuCanvas, pipeline); 14 | } 15 | 16 | render(renderPassAPI: RenderPassAPI, vertexData: VertexBuffers): Program { 17 | super.render(renderPassAPI); 18 | renderPassAPI.setVertexBuffer(0, vertexData.position.data); 19 | renderPassAPI.draw(3); 20 | 21 | return this; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/programs/DefaultProgram.ts: -------------------------------------------------------------------------------- 1 | import { VEC3_SIZE } from "./constants"; 2 | import { 3 | Pipeline, 4 | RenderPassAPI, 5 | GPUCanvas, 6 | VertexBuffers, 7 | LightModelPosition, 8 | } from "../types"; 9 | import Program from "./Program"; 10 | import defaultShaderData from "./shaders/defaultShader"; 11 | 12 | export default class DefaultProgram extends Program { 13 | private lightModelBuffer: GPUBuffer; 14 | private lightModelBindGroup: GPUBindGroup; 15 | private constructor(gpuCanvas: GPUCanvas, pipeline: Pipeline) { 16 | super(gpuCanvas, pipeline); 17 | this.lightModelBuffer = this.gl.createUniformBuffer(VEC3_SIZE); 18 | this.lightModelBindGroup = this.gl.createBindGroup({ 19 | layout: pipeline.getBindGroupLayout(2), 20 | entries: [ 21 | { 22 | binding: 0, 23 | resource: { 24 | buffer: this.lightModelBuffer, 25 | }, 26 | }, 27 | ], 28 | }); 29 | } 30 | 31 | static init(gpuCanvas: GPUCanvas) { 32 | const shader = gpuCanvas.createShader(defaultShaderData); 33 | const pipeline = gpuCanvas.createRenderPipeline(shader); 34 | return new DefaultProgram(gpuCanvas, pipeline); 35 | } 36 | 37 | updateLightModelPositionUniform( 38 | lightModelPosition: LightModelPosition 39 | ): DefaultProgram { 40 | this.gl.updateUniform( 41 | this.lightModelBuffer, 42 | lightModelPosition as Float32Array, 43 | 0 44 | ); 45 | return this; 46 | } 47 | 48 | render( 49 | renderPassAPI: RenderPassAPI, 50 | vertexData: VertexBuffers 51 | ): DefaultProgram { 52 | super.render(renderPassAPI); 53 | renderPassAPI.setBindGroup(2, this.lightModelBindGroup); 54 | renderPassAPI.setVertexBuffer(0, vertexData.position.data); 55 | renderPassAPI.setVertexBuffer(1, vertexData.normals.data); 56 | renderPassAPI.setIndexBuffer(vertexData.indices.data, "uint16"); 57 | renderPassAPI.drawIndexed(vertexData.indices.length); 58 | return this; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/programs/Program.ts: -------------------------------------------------------------------------------- 1 | import Camera from "../PerspectiveCamera"; 2 | import { MAT4_SIZE, VEC3_SIZE } from "./constants"; 3 | import { GPUCanvas, ModelMatrix, NormalMatrix, RenderPassAPI } from "../types"; 4 | 5 | export default class Program { 6 | protected modelMatrixBuffer: GPUBuffer; 7 | protected normalMatrixBuffer: GPUBuffer; 8 | protected viewMatrixBuffer: GPUBuffer; 9 | protected projectionMatrixBuffer: GPUBuffer; 10 | protected cameraPositionBuffer: GPUBuffer; 11 | protected cameraUniformBindGroup: GPUBindGroup; 12 | protected modelBindGroups: GPUBindGroup[]; 13 | protected pipeline: GPURenderPipeline; 14 | protected gl: GPUCanvas; 15 | modelBindIndex: number; 16 | constructor(gpuCanvas: GPUCanvas, pipeline: GPURenderPipeline) { 17 | this.pipeline = pipeline; 18 | this.gl = gpuCanvas; 19 | this.modelBindIndex = 0; 20 | 21 | this.viewMatrixBuffer = this.gl.createUniformBuffer(MAT4_SIZE); 22 | this.projectionMatrixBuffer = this.gl.createUniformBuffer(MAT4_SIZE); 23 | this.modelMatrixBuffer = this.gl.createUniformBuffer(MAT4_SIZE); 24 | this.normalMatrixBuffer = this.gl.createUniformBuffer(MAT4_SIZE); 25 | this.cameraPositionBuffer = this.gl.createUniformBuffer(VEC3_SIZE); 26 | 27 | this.cameraUniformBindGroup = this.gl.createBindGroup({ 28 | layout: pipeline.getBindGroupLayout(0), 29 | entries: [ 30 | { 31 | binding: 0, 32 | resource: { 33 | buffer: this.viewMatrixBuffer, 34 | }, 35 | }, 36 | { 37 | binding: 1, 38 | resource: { 39 | buffer: this.projectionMatrixBuffer, 40 | }, 41 | }, 42 | { 43 | binding: 2, 44 | resource: { 45 | buffer: this.cameraPositionBuffer, 46 | }, 47 | }, 48 | ], 49 | }); 50 | 51 | this.modelBindGroups = []; 52 | } 53 | 54 | registerModelMatrices(numberOfModels: number): number[] { 55 | const offsetPerModel = 256; 56 | const totalOffset = offsetPerModel * (numberOfModels - 1); 57 | const matrixSize = 16 * Float32Array.BYTES_PER_ELEMENT; 58 | 59 | this.modelMatrixBuffer = this.gl.createUniformBuffer( 60 | matrixSize + totalOffset 61 | ); 62 | 63 | this.normalMatrixBuffer = this.gl.createUniformBuffer( 64 | matrixSize + totalOffset 65 | ); 66 | 67 | const indices = []; 68 | 69 | for (let i = 0; i < numberOfModels; i++) { 70 | const bindGroup = this.gl.createBindGroup({ 71 | layout: this.pipeline.getBindGroupLayout(1), 72 | entries: [ 73 | { 74 | binding: 0, 75 | resource: { 76 | buffer: this.modelMatrixBuffer, 77 | offset: i * offsetPerModel, 78 | size: matrixSize, 79 | }, 80 | }, 81 | { 82 | binding: 1, 83 | resource: { 84 | buffer: this.normalMatrixBuffer, 85 | offset: i * offsetPerModel, 86 | size: matrixSize, 87 | }, 88 | }, 89 | ], 90 | }); 91 | this.modelBindGroups.push(bindGroup); 92 | indices.push(i); 93 | } 94 | 95 | return indices; 96 | } 97 | 98 | updateCameraUniforms(camera: Camera): this { 99 | this.gl.updateUniform( 100 | this.projectionMatrixBuffer, 101 | camera.projectionMatrix as Float32Array, 102 | 0 103 | ); 104 | 105 | this.gl.updateUniform( 106 | this.viewMatrixBuffer, 107 | camera.viewMatrix as Float32Array, 108 | 0 109 | ); 110 | 111 | this.gl.updateUniform( 112 | this.cameraPositionBuffer, 113 | camera.translation as Float32Array, 114 | 0 115 | ); 116 | 117 | return this; 118 | } 119 | 120 | updateModelUniforms( 121 | modelMatrix: ModelMatrix, 122 | normalMatrix: NormalMatrix, 123 | modelBindIndex: number 124 | ): this { 125 | this.modelBindIndex = modelBindIndex; 126 | 127 | this.gl.updateUniform( 128 | this.modelMatrixBuffer, 129 | modelMatrix as Float32Array, 130 | 256 * modelBindIndex 131 | ); 132 | 133 | this.gl.updateUniform( 134 | this.normalMatrixBuffer, 135 | normalMatrix as Float32Array, 136 | 256 * modelBindIndex 137 | ); 138 | 139 | return this; 140 | } 141 | activate(renderPassAPI: RenderPassAPI): this { 142 | renderPassAPI.setPipeline(this.pipeline); 143 | return this; 144 | } 145 | render(renderPassAPI: RenderPassAPI, ...args: any[]): Program { 146 | renderPassAPI.setBindGroup(0, this.cameraUniformBindGroup); 147 | renderPassAPI.setBindGroup(1, this.modelBindGroups[this.modelBindIndex]); 148 | return this; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/programs/constants.ts: -------------------------------------------------------------------------------- 1 | export const MAT4_SIZE = 16 * Float32Array.BYTES_PER_ELEMENT; 2 | export const VEC3_SIZE = 3 * Float32Array.BYTES_PER_ELEMENT; 3 | export const VEC4_SIZE = 4 * Float32Array.BYTES_PER_ELEMENT; 4 | -------------------------------------------------------------------------------- /src/programs/shaders/debuggerShader.ts: -------------------------------------------------------------------------------- 1 | import { RawShaderData } from "../../types"; 2 | 3 | const FRAGMENT_ENTRY_POINT = "fragment_main"; 4 | const VERTEX_ENTRY_POINT = "vertex_main"; 5 | const STEP_MODE = "vertex"; 6 | const FORMAT = "float32x3"; 7 | const STRIDE = Float32Array.BYTES_PER_ELEMENT * 3; 8 | 9 | const code = ` 10 | struct VertexOut { 11 | @builtin(position) position : vec4, 12 | }; 13 | 14 | @binding(0) @group(0) var viewMatrix : mat4x4; 15 | @binding(1) @group(0) var projectionMatrix : mat4x4; 16 | @binding(2) @group(0) var cameraPosition : vec3; 17 | @group(1) @binding(0) var modelMatrix : mat4x4; 18 | @group(1) @binding(1) var normalMatrix : mat4x4; 19 | 20 | @vertex 21 | fn ${VERTEX_ENTRY_POINT}(@location(0) position: vec4) -> VertexOut 22 | { 23 | let normalMatrix = normalMatrix; 24 | let cameraPosition = cameraPosition; 25 | var output : VertexOut; 26 | output.position = projectionMatrix * viewMatrix * modelMatrix * position; 27 | return output; 28 | } 29 | 30 | @fragment 31 | fn ${FRAGMENT_ENTRY_POINT}(fragData: VertexOut) -> @location(0) vec4 32 | { 33 | return vec4(0.0, 1.0, 0.0, 1.0); 34 | } 35 | `; 36 | 37 | export default { 38 | code, 39 | primitive: { 40 | topology: "triangle-list", 41 | cullMode: "back", 42 | }, 43 | fragment: { 44 | entryPoint: FRAGMENT_ENTRY_POINT, 45 | }, 46 | vertex: { 47 | entryPoint: VERTEX_ENTRY_POINT, 48 | buffers: [ 49 | { 50 | arrayStride: STRIDE, 51 | attributes: [ 52 | { 53 | format: FORMAT, 54 | offset: 0, 55 | shaderLocation: 0, 56 | }, 57 | ], 58 | stepMode: STEP_MODE, 59 | }, 60 | ], 61 | }, 62 | } as RawShaderData; 63 | -------------------------------------------------------------------------------- /src/programs/shaders/defaultShader.ts: -------------------------------------------------------------------------------- 1 | import { RawShaderData } from "../../types"; 2 | 3 | const FRAGMENT_ENTRY_POINT = "fragment_main"; 4 | const VERTEX_ENTRY_POINT = "vertex_main"; 5 | const STEP_MODE = "vertex"; 6 | const FORMAT = "float32x3"; 7 | const STRIDE = Float32Array.BYTES_PER_ELEMENT * 3; 8 | 9 | const code = ` 10 | struct VertexOut { 11 | @builtin(position) position : vec4, 12 | @location(1) vPos: vec4, 13 | @location(2) vNormal: vec4, 14 | }; 15 | 16 | @group(0) @binding(0) var viewMatrix : mat4x4; 17 | @group(0) @binding(1) var projectionMatrix : mat4x4; 18 | @group(0) @binding(2) var cameraPosition : vec3; 19 | @group(1) @binding(0) var modelMatrix : mat4x4; 20 | @group(1) @binding(1) var normalMatrix : mat4x4; 21 | @group(2) @binding(0) var lightModelPosition : vec3; 22 | 23 | @vertex 24 | fn ${VERTEX_ENTRY_POINT}( 25 | @location(0) position: vec4, 26 | @location(1) normal: vec4) -> VertexOut 27 | { 28 | var output : VertexOut; 29 | output.position = projectionMatrix * viewMatrix * modelMatrix * position; 30 | output.vNormal = normalMatrix * abs(normal); 31 | output.vPos = modelMatrix * position; 32 | return output; 33 | } 34 | 35 | @fragment 36 | fn ${FRAGMENT_ENTRY_POINT}(fragData: VertexOut) -> @location(0) vec4 37 | { 38 | let diffuseLightStrength = 0.9; 39 | let ambientLightIntensity = 0.0; 40 | let specularStrength = 0.2; 41 | let specularShininess = 32.; 42 | 43 | let vNormal = normalize(fragData.vNormal.xyz); 44 | let vPosition = fragData.vPos.xyz; 45 | let vCameraPosition = cameraPosition; 46 | let lightPosition = lightModelPosition.xyz; 47 | 48 | let lightDir = normalize(lightPosition - vPosition); 49 | let lightMagnitude = dot(vNormal, lightDir); 50 | let diffuseLightFinal: f32 = diffuseLightStrength * max(lightMagnitude, 0); 51 | 52 | let viewDir = normalize(vCameraPosition - vPosition); 53 | let reflectDir = reflect(-lightDir, vNormal); 54 | let spec = pow(max(dot(viewDir, reflectDir), 0.0), specularShininess); 55 | let specularFinal = specularStrength * spec; 56 | 57 | let lightFinal = specularFinal + diffuseLightFinal + ambientLightIntensity; 58 | // return vec4(vNormal, 1.0) * lightFinal; 59 | return vec4(0.8, 0.0, 0.0, 1.0) * lightFinal; 60 | } 61 | `; 62 | 63 | export default { 64 | code, 65 | primitive: { 66 | topology: "triangle-list", 67 | frontFace: "ccw", 68 | cullMode: "back", 69 | }, 70 | fragment: { 71 | entryPoint: FRAGMENT_ENTRY_POINT, 72 | }, 73 | vertex: { 74 | entryPoint: VERTEX_ENTRY_POINT, 75 | buffers: [ 76 | { 77 | arrayStride: STRIDE, 78 | attributes: [ 79 | { 80 | format: FORMAT, 81 | offset: 0, 82 | shaderLocation: 0, 83 | }, 84 | ], 85 | stepMode: STEP_MODE, 86 | }, 87 | { 88 | arrayStride: STRIDE, 89 | attributes: [ 90 | { 91 | format: FORMAT, 92 | offset: 0, 93 | shaderLocation: 1, 94 | }, 95 | ], 96 | stepMode: STEP_MODE, 97 | }, 98 | ], 99 | }, 100 | } as RawShaderData; 101 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: black; 3 | } 4 | 5 | canvas { 6 | width: 100%; 7 | height: 100%; 8 | } 9 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { mat4, vec3 } from "gl-matrix"; 2 | 3 | import type Camera from "./PerspectiveCamera"; 4 | import type GPUCanvas from "./WebGPUCanvas"; 5 | 6 | export { Camera, GPUCanvas }; 7 | 8 | type Length = number; 9 | 10 | export interface Mesh { 11 | positions: Float32Array; 12 | uvs: Float32Array; 13 | normals: Float32Array; 14 | indices: Uint16Array; 15 | } 16 | 17 | export interface MeshGPUBuffer { 18 | data: GPUBuffer; 19 | length: Length; 20 | } 21 | 22 | export interface VertexBuffers { 23 | position: MeshGPUBuffer; 24 | uvs: MeshGPUBuffer; 25 | normals: MeshGPUBuffer; 26 | indices: MeshGPUBuffer; 27 | } 28 | 29 | export interface UniformGPUBindGroup { 30 | bindGroup: GPUBindGroup; 31 | binding: number; 32 | } 33 | 34 | export type TransformationMatrix = mat4; 35 | export type ModelMatrix = mat4; 36 | export type NormalMatrix = mat4; 37 | export type ViewMatrix = mat4; 38 | export type ProjectionMatrix = mat4; 39 | export type LightModelPosition = vec3; 40 | 41 | export interface RawShaderData { 42 | code: string; 43 | primitive: GPUPrimitiveState; 44 | vertex: Omit; 45 | fragment: Omit; 46 | } 47 | 48 | export interface Shader { 49 | vertex: GPUVertexState; 50 | fragment: GPUFragmentState; 51 | } 52 | 53 | export type RenderPassAPI = GPURenderPassEncoder; 54 | export type Pipeline = GPURenderPipeline; 55 | -------------------------------------------------------------------------------- /static/cloth_20_30_l.obj: -------------------------------------------------------------------------------- 1 | # Blender v3.0.0 OBJ File: 'cloth_30_45_l.blend' 2 | # www.blender.org 3 | mtllib cloth_20_30_l.mtl 4 | o Grid 5 | v -0.500000 -0.750000 -0.000000 6 | v -0.450000 -0.750000 -0.000000 7 | v -0.400000 -0.750000 -0.000000 8 | v -0.350000 -0.750000 -0.000000 9 | v -0.300000 -0.750000 -0.000000 10 | v -0.250000 -0.750000 -0.000000 11 | v -0.200000 -0.750000 -0.000000 12 | v -0.150000 -0.750000 -0.000000 13 | v -0.100000 -0.750000 -0.000000 14 | v -0.050000 -0.750000 -0.000000 15 | v 0.000000 -0.750000 -0.000000 16 | v 0.050000 -0.750000 -0.000000 17 | v 0.100000 -0.750000 -0.000000 18 | v 0.150000 -0.750000 -0.000000 19 | v 0.200000 -0.750000 -0.000000 20 | v 0.250000 -0.750000 -0.000000 21 | v 0.300000 -0.750000 -0.000000 22 | v 0.350000 -0.750000 -0.000000 23 | v 0.400000 -0.750000 -0.000000 24 | v 0.450000 -0.750000 -0.000000 25 | v 0.500000 -0.750000 -0.000000 26 | v -0.500000 -0.700000 -0.000000 27 | v -0.450000 -0.700000 -0.000000 28 | v -0.400000 -0.700000 -0.000000 29 | v -0.350000 -0.700000 -0.000000 30 | v -0.300000 -0.700000 -0.000000 31 | v -0.250000 -0.700000 -0.000000 32 | v -0.200000 -0.700000 -0.000000 33 | v -0.150000 -0.700000 -0.000000 34 | v -0.100000 -0.700000 -0.000000 35 | v -0.050000 -0.700000 -0.000000 36 | v 0.000000 -0.700000 -0.000000 37 | v 0.050000 -0.700000 -0.000000 38 | v 0.100000 -0.700000 -0.000000 39 | v 0.150000 -0.700000 -0.000000 40 | v 0.200000 -0.700000 -0.000000 41 | v 0.250000 -0.700000 -0.000000 42 | v 0.300000 -0.700000 -0.000000 43 | v 0.350000 -0.700000 -0.000000 44 | v 0.400000 -0.700000 -0.000000 45 | v 0.450000 -0.700000 -0.000000 46 | v 0.500000 -0.700000 -0.000000 47 | v -0.500000 -0.650000 -0.000000 48 | v -0.450000 -0.650000 -0.000000 49 | v -0.400000 -0.650000 -0.000000 50 | v -0.350000 -0.650000 -0.000000 51 | v -0.300000 -0.650000 -0.000000 52 | v -0.250000 -0.650000 -0.000000 53 | v -0.200000 -0.650000 -0.000000 54 | v -0.150000 -0.650000 -0.000000 55 | v -0.100000 -0.650000 -0.000000 56 | v -0.050000 -0.650000 -0.000000 57 | v 0.000000 -0.650000 -0.000000 58 | v 0.050000 -0.650000 -0.000000 59 | v 0.100000 -0.650000 -0.000000 60 | v 0.150000 -0.650000 -0.000000 61 | v 0.200000 -0.650000 -0.000000 62 | v 0.250000 -0.650000 -0.000000 63 | v 0.300000 -0.650000 -0.000000 64 | v 0.350000 -0.650000 -0.000000 65 | v 0.400000 -0.650000 -0.000000 66 | v 0.450000 -0.650000 -0.000000 67 | v 0.500000 -0.650000 -0.000000 68 | v -0.500000 -0.600000 -0.000000 69 | v -0.450000 -0.600000 -0.000000 70 | v -0.400000 -0.600000 -0.000000 71 | v -0.350000 -0.600000 -0.000000 72 | v -0.300000 -0.600000 -0.000000 73 | v -0.250000 -0.600000 -0.000000 74 | v -0.200000 -0.600000 -0.000000 75 | v -0.150000 -0.600000 -0.000000 76 | v -0.100000 -0.600000 -0.000000 77 | v -0.050000 -0.600000 -0.000000 78 | v 0.000000 -0.600000 -0.000000 79 | v 0.050000 -0.600000 -0.000000 80 | v 0.100000 -0.600000 -0.000000 81 | v 0.150000 -0.600000 -0.000000 82 | v 0.200000 -0.600000 -0.000000 83 | v 0.250000 -0.600000 -0.000000 84 | v 0.300000 -0.600000 -0.000000 85 | v 0.350000 -0.600000 -0.000000 86 | v 0.400000 -0.600000 -0.000000 87 | v 0.450000 -0.600000 -0.000000 88 | v 0.500000 -0.600000 -0.000000 89 | v -0.500000 -0.550000 -0.000000 90 | v -0.450000 -0.550000 -0.000000 91 | v -0.400000 -0.550000 -0.000000 92 | v -0.350000 -0.550000 -0.000000 93 | v -0.300000 -0.550000 -0.000000 94 | v -0.250000 -0.550000 -0.000000 95 | v -0.200000 -0.550000 -0.000000 96 | v -0.150000 -0.550000 -0.000000 97 | v -0.100000 -0.550000 -0.000000 98 | v -0.050000 -0.550000 -0.000000 99 | v 0.000000 -0.550000 -0.000000 100 | v 0.050000 -0.550000 -0.000000 101 | v 0.100000 -0.550000 -0.000000 102 | v 0.150000 -0.550000 -0.000000 103 | v 0.200000 -0.550000 -0.000000 104 | v 0.250000 -0.550000 -0.000000 105 | v 0.300000 -0.550000 -0.000000 106 | v 0.350000 -0.550000 -0.000000 107 | v 0.400000 -0.550000 -0.000000 108 | v 0.450000 -0.550000 -0.000000 109 | v 0.500000 -0.550000 -0.000000 110 | v -0.500000 -0.500000 -0.000000 111 | v -0.450000 -0.500000 -0.000000 112 | v -0.400000 -0.500000 -0.000000 113 | v -0.350000 -0.500000 -0.000000 114 | v -0.300000 -0.500000 -0.000000 115 | v -0.250000 -0.500000 -0.000000 116 | v -0.200000 -0.500000 -0.000000 117 | v -0.150000 -0.500000 -0.000000 118 | v -0.100000 -0.500000 -0.000000 119 | v -0.050000 -0.500000 -0.000000 120 | v 0.000000 -0.500000 -0.000000 121 | v 0.050000 -0.500000 -0.000000 122 | v 0.100000 -0.500000 -0.000000 123 | v 0.150000 -0.500000 -0.000000 124 | v 0.200000 -0.500000 -0.000000 125 | v 0.250000 -0.500000 -0.000000 126 | v 0.300000 -0.500000 -0.000000 127 | v 0.350000 -0.500000 -0.000000 128 | v 0.400000 -0.500000 -0.000000 129 | v 0.450000 -0.500000 -0.000000 130 | v 0.500000 -0.500000 -0.000000 131 | v -0.500000 -0.450000 -0.000000 132 | v -0.450000 -0.450000 -0.000000 133 | v -0.400000 -0.450000 -0.000000 134 | v -0.350000 -0.450000 -0.000000 135 | v -0.300000 -0.450000 -0.000000 136 | v -0.250000 -0.450000 -0.000000 137 | v -0.200000 -0.450000 -0.000000 138 | v -0.150000 -0.450000 -0.000000 139 | v -0.100000 -0.450000 -0.000000 140 | v -0.050000 -0.450000 -0.000000 141 | v 0.000000 -0.450000 -0.000000 142 | v 0.050000 -0.450000 -0.000000 143 | v 0.100000 -0.450000 -0.000000 144 | v 0.150000 -0.450000 -0.000000 145 | v 0.200000 -0.450000 -0.000000 146 | v 0.250000 -0.450000 -0.000000 147 | v 0.300000 -0.450000 -0.000000 148 | v 0.350000 -0.450000 -0.000000 149 | v 0.400000 -0.450000 -0.000000 150 | v 0.450000 -0.450000 -0.000000 151 | v 0.500000 -0.450000 -0.000000 152 | v -0.500000 -0.400000 -0.000000 153 | v -0.450000 -0.400000 -0.000000 154 | v -0.400000 -0.400000 -0.000000 155 | v -0.350000 -0.400000 -0.000000 156 | v -0.300000 -0.400000 -0.000000 157 | v -0.250000 -0.400000 -0.000000 158 | v -0.200000 -0.400000 -0.000000 159 | v -0.150000 -0.400000 -0.000000 160 | v -0.100000 -0.400000 -0.000000 161 | v -0.050000 -0.400000 -0.000000 162 | v 0.000000 -0.400000 -0.000000 163 | v 0.050000 -0.400000 -0.000000 164 | v 0.100000 -0.400000 -0.000000 165 | v 0.150000 -0.400000 -0.000000 166 | v 0.200000 -0.400000 -0.000000 167 | v 0.250000 -0.400000 -0.000000 168 | v 0.300000 -0.400000 -0.000000 169 | v 0.350000 -0.400000 -0.000000 170 | v 0.400000 -0.400000 -0.000000 171 | v 0.450000 -0.400000 -0.000000 172 | v 0.500000 -0.400000 -0.000000 173 | v -0.500000 -0.350000 -0.000000 174 | v -0.450000 -0.350000 -0.000000 175 | v -0.400000 -0.350000 -0.000000 176 | v -0.350000 -0.350000 -0.000000 177 | v -0.300000 -0.350000 -0.000000 178 | v -0.250000 -0.350000 -0.000000 179 | v -0.200000 -0.350000 -0.000000 180 | v -0.150000 -0.350000 -0.000000 181 | v -0.100000 -0.350000 -0.000000 182 | v -0.050000 -0.350000 -0.000000 183 | v 0.000000 -0.350000 -0.000000 184 | v 0.050000 -0.350000 -0.000000 185 | v 0.100000 -0.350000 -0.000000 186 | v 0.150000 -0.350000 -0.000000 187 | v 0.200000 -0.350000 -0.000000 188 | v 0.250000 -0.350000 -0.000000 189 | v 0.300000 -0.350000 -0.000000 190 | v 0.350000 -0.350000 -0.000000 191 | v 0.400000 -0.350000 -0.000000 192 | v 0.450000 -0.350000 -0.000000 193 | v 0.500000 -0.350000 -0.000000 194 | v -0.500000 -0.300000 -0.000000 195 | v -0.450000 -0.300000 -0.000000 196 | v -0.400000 -0.300000 -0.000000 197 | v -0.350000 -0.300000 -0.000000 198 | v -0.300000 -0.300000 -0.000000 199 | v -0.250000 -0.300000 -0.000000 200 | v -0.200000 -0.300000 -0.000000 201 | v -0.150000 -0.300000 -0.000000 202 | v -0.100000 -0.300000 -0.000000 203 | v -0.050000 -0.300000 -0.000000 204 | v 0.000000 -0.300000 -0.000000 205 | v 0.050000 -0.300000 -0.000000 206 | v 0.100000 -0.300000 -0.000000 207 | v 0.150000 -0.300000 -0.000000 208 | v 0.200000 -0.300000 -0.000000 209 | v 0.250000 -0.300000 -0.000000 210 | v 0.300000 -0.300000 -0.000000 211 | v 0.350000 -0.300000 -0.000000 212 | v 0.400000 -0.300000 -0.000000 213 | v 0.450000 -0.300000 -0.000000 214 | v 0.500000 -0.300000 -0.000000 215 | v -0.500000 -0.250000 -0.000000 216 | v -0.450000 -0.250000 -0.000000 217 | v -0.400000 -0.250000 -0.000000 218 | v -0.350000 -0.250000 -0.000000 219 | v -0.300000 -0.250000 -0.000000 220 | v -0.250000 -0.250000 -0.000000 221 | v -0.200000 -0.250000 -0.000000 222 | v -0.150000 -0.250000 -0.000000 223 | v -0.100000 -0.250000 -0.000000 224 | v -0.050000 -0.250000 -0.000000 225 | v 0.000000 -0.250000 -0.000000 226 | v 0.050000 -0.250000 -0.000000 227 | v 0.100000 -0.250000 -0.000000 228 | v 0.150000 -0.250000 -0.000000 229 | v 0.200000 -0.250000 -0.000000 230 | v 0.250000 -0.250000 -0.000000 231 | v 0.300000 -0.250000 -0.000000 232 | v 0.350000 -0.250000 -0.000000 233 | v 0.400000 -0.250000 -0.000000 234 | v 0.450000 -0.250000 -0.000000 235 | v 0.500000 -0.250000 -0.000000 236 | v -0.500000 -0.200000 -0.000000 237 | v -0.450000 -0.200000 -0.000000 238 | v -0.400000 -0.200000 -0.000000 239 | v -0.350000 -0.200000 -0.000000 240 | v -0.300000 -0.200000 -0.000000 241 | v -0.250000 -0.200000 -0.000000 242 | v -0.200000 -0.200000 -0.000000 243 | v -0.150000 -0.200000 -0.000000 244 | v -0.100000 -0.200000 -0.000000 245 | v -0.050000 -0.200000 -0.000000 246 | v 0.000000 -0.200000 -0.000000 247 | v 0.050000 -0.200000 -0.000000 248 | v 0.100000 -0.200000 -0.000000 249 | v 0.150000 -0.200000 -0.000000 250 | v 0.200000 -0.200000 -0.000000 251 | v 0.250000 -0.200000 -0.000000 252 | v 0.300000 -0.200000 -0.000000 253 | v 0.350000 -0.200000 -0.000000 254 | v 0.400000 -0.200000 -0.000000 255 | v 0.450000 -0.200000 -0.000000 256 | v 0.500000 -0.200000 -0.000000 257 | v -0.500000 -0.150000 -0.000000 258 | v -0.450000 -0.150000 -0.000000 259 | v -0.400000 -0.150000 -0.000000 260 | v -0.350000 -0.150000 -0.000000 261 | v -0.300000 -0.150000 -0.000000 262 | v -0.250000 -0.150000 -0.000000 263 | v -0.200000 -0.150000 -0.000000 264 | v -0.150000 -0.150000 -0.000000 265 | v -0.100000 -0.150000 -0.000000 266 | v -0.050000 -0.150000 -0.000000 267 | v 0.000000 -0.150000 -0.000000 268 | v 0.050000 -0.150000 -0.000000 269 | v 0.100000 -0.150000 -0.000000 270 | v 0.150000 -0.150000 -0.000000 271 | v 0.200000 -0.150000 -0.000000 272 | v 0.250000 -0.150000 -0.000000 273 | v 0.300000 -0.150000 -0.000000 274 | v 0.350000 -0.150000 -0.000000 275 | v 0.400000 -0.150000 -0.000000 276 | v 0.450000 -0.150000 -0.000000 277 | v 0.500000 -0.150000 -0.000000 278 | v -0.500000 -0.100000 -0.000000 279 | v -0.450000 -0.100000 -0.000000 280 | v -0.400000 -0.100000 -0.000000 281 | v -0.350000 -0.100000 -0.000000 282 | v -0.300000 -0.100000 -0.000000 283 | v -0.250000 -0.100000 -0.000000 284 | v -0.200000 -0.100000 -0.000000 285 | v -0.150000 -0.100000 -0.000000 286 | v -0.100000 -0.100000 -0.000000 287 | v -0.050000 -0.100000 -0.000000 288 | v 0.000000 -0.100000 -0.000000 289 | v 0.050000 -0.100000 -0.000000 290 | v 0.100000 -0.100000 -0.000000 291 | v 0.150000 -0.100000 -0.000000 292 | v 0.200000 -0.100000 -0.000000 293 | v 0.250000 -0.100000 -0.000000 294 | v 0.300000 -0.100000 -0.000000 295 | v 0.350000 -0.100000 -0.000000 296 | v 0.400000 -0.100000 -0.000000 297 | v 0.450000 -0.100000 -0.000000 298 | v 0.500000 -0.100000 -0.000000 299 | v -0.500000 -0.050000 -0.000000 300 | v -0.450000 -0.050000 -0.000000 301 | v -0.400000 -0.050000 -0.000000 302 | v -0.350000 -0.050000 -0.000000 303 | v -0.300000 -0.050000 -0.000000 304 | v -0.250000 -0.050000 -0.000000 305 | v -0.200000 -0.050000 -0.000000 306 | v -0.150000 -0.050000 -0.000000 307 | v -0.100000 -0.050000 -0.000000 308 | v -0.050000 -0.050000 -0.000000 309 | v 0.000000 -0.050000 -0.000000 310 | v 0.050000 -0.050000 -0.000000 311 | v 0.100000 -0.050000 -0.000000 312 | v 0.150000 -0.050000 -0.000000 313 | v 0.200000 -0.050000 -0.000000 314 | v 0.250000 -0.050000 -0.000000 315 | v 0.300000 -0.050000 -0.000000 316 | v 0.350000 -0.050000 -0.000000 317 | v 0.400000 -0.050000 -0.000000 318 | v 0.450000 -0.050000 -0.000000 319 | v 0.500000 -0.050000 -0.000000 320 | v -0.500000 0.000000 0.000000 321 | v -0.450000 0.000000 0.000000 322 | v -0.400000 0.000000 0.000000 323 | v -0.350000 0.000000 0.000000 324 | v -0.300000 0.000000 0.000000 325 | v -0.250000 0.000000 0.000000 326 | v -0.200000 0.000000 0.000000 327 | v -0.150000 0.000000 0.000000 328 | v -0.100000 0.000000 0.000000 329 | v -0.050000 0.000000 0.000000 330 | v 0.000000 0.000000 0.000000 331 | v 0.050000 0.000000 0.000000 332 | v 0.100000 0.000000 0.000000 333 | v 0.150000 0.000000 0.000000 334 | v 0.200000 0.000000 0.000000 335 | v 0.250000 0.000000 0.000000 336 | v 0.300000 0.000000 0.000000 337 | v 0.350000 0.000000 0.000000 338 | v 0.400000 0.000000 0.000000 339 | v 0.450000 0.000000 0.000000 340 | v 0.500000 0.000000 0.000000 341 | v -0.500000 0.050000 0.000000 342 | v -0.450000 0.050000 0.000000 343 | v -0.400000 0.050000 0.000000 344 | v -0.350000 0.050000 0.000000 345 | v -0.300000 0.050000 0.000000 346 | v -0.250000 0.050000 0.000000 347 | v -0.200000 0.050000 0.000000 348 | v -0.150000 0.050000 0.000000 349 | v -0.100000 0.050000 0.000000 350 | v -0.050000 0.050000 0.000000 351 | v 0.000000 0.050000 0.000000 352 | v 0.050000 0.050000 0.000000 353 | v 0.100000 0.050000 0.000000 354 | v 0.150000 0.050000 0.000000 355 | v 0.200000 0.050000 0.000000 356 | v 0.250000 0.050000 0.000000 357 | v 0.300000 0.050000 0.000000 358 | v 0.350000 0.050000 0.000000 359 | v 0.400000 0.050000 0.000000 360 | v 0.450000 0.050000 0.000000 361 | v 0.500000 0.050000 0.000000 362 | v -0.500000 0.100000 0.000000 363 | v -0.450000 0.100000 0.000000 364 | v -0.400000 0.100000 0.000000 365 | v -0.350000 0.100000 0.000000 366 | v -0.300000 0.100000 0.000000 367 | v -0.250000 0.100000 0.000000 368 | v -0.200000 0.100000 0.000000 369 | v -0.150000 0.100000 0.000000 370 | v -0.100000 0.100000 0.000000 371 | v -0.050000 0.100000 0.000000 372 | v 0.000000 0.100000 0.000000 373 | v 0.050000 0.100000 0.000000 374 | v 0.100000 0.100000 0.000000 375 | v 0.150000 0.100000 0.000000 376 | v 0.200000 0.100000 0.000000 377 | v 0.250000 0.100000 0.000000 378 | v 0.300000 0.100000 0.000000 379 | v 0.350000 0.100000 0.000000 380 | v 0.400000 0.100000 0.000000 381 | v 0.450000 0.100000 0.000000 382 | v 0.500000 0.100000 0.000000 383 | v -0.500000 0.150000 0.000000 384 | v -0.450000 0.150000 0.000000 385 | v -0.400000 0.150000 0.000000 386 | v -0.350000 0.150000 0.000000 387 | v -0.300000 0.150000 0.000000 388 | v -0.250000 0.150000 0.000000 389 | v -0.200000 0.150000 0.000000 390 | v -0.150000 0.150000 0.000000 391 | v -0.100000 0.150000 0.000000 392 | v -0.050000 0.150000 0.000000 393 | v 0.000000 0.150000 0.000000 394 | v 0.050000 0.150000 0.000000 395 | v 0.100000 0.150000 0.000000 396 | v 0.150000 0.150000 0.000000 397 | v 0.200000 0.150000 0.000000 398 | v 0.250000 0.150000 0.000000 399 | v 0.300000 0.150000 0.000000 400 | v 0.350000 0.150000 0.000000 401 | v 0.400000 0.150000 0.000000 402 | v 0.450000 0.150000 0.000000 403 | v 0.500000 0.150000 0.000000 404 | v -0.500000 0.200000 0.000000 405 | v -0.450000 0.200000 0.000000 406 | v -0.400000 0.200000 0.000000 407 | v -0.350000 0.200000 0.000000 408 | v -0.300000 0.200000 0.000000 409 | v -0.250000 0.200000 0.000000 410 | v -0.200000 0.200000 0.000000 411 | v -0.150000 0.200000 0.000000 412 | v -0.100000 0.200000 0.000000 413 | v -0.050000 0.200000 0.000000 414 | v 0.000000 0.200000 0.000000 415 | v 0.050000 0.200000 0.000000 416 | v 0.100000 0.200000 0.000000 417 | v 0.150000 0.200000 0.000000 418 | v 0.200000 0.200000 0.000000 419 | v 0.250000 0.200000 0.000000 420 | v 0.300000 0.200000 0.000000 421 | v 0.350000 0.200000 0.000000 422 | v 0.400000 0.200000 0.000000 423 | v 0.450000 0.200000 0.000000 424 | v 0.500000 0.200000 0.000000 425 | v -0.500000 0.250000 0.000000 426 | v -0.450000 0.250000 0.000000 427 | v -0.400000 0.250000 0.000000 428 | v -0.350000 0.250000 0.000000 429 | v -0.300000 0.250000 0.000000 430 | v -0.250000 0.250000 0.000000 431 | v -0.200000 0.250000 0.000000 432 | v -0.150000 0.250000 0.000000 433 | v -0.100000 0.250000 0.000000 434 | v -0.050000 0.250000 0.000000 435 | v 0.000000 0.250000 0.000000 436 | v 0.050000 0.250000 0.000000 437 | v 0.100000 0.250000 0.000000 438 | v 0.150000 0.250000 0.000000 439 | v 0.200000 0.250000 0.000000 440 | v 0.250000 0.250000 0.000000 441 | v 0.300000 0.250000 0.000000 442 | v 0.350000 0.250000 0.000000 443 | v 0.400000 0.250000 0.000000 444 | v 0.450000 0.250000 0.000000 445 | v 0.500000 0.250000 0.000000 446 | v -0.500000 0.300000 0.000000 447 | v -0.450000 0.300000 0.000000 448 | v -0.400000 0.300000 0.000000 449 | v -0.350000 0.300000 0.000000 450 | v -0.300000 0.300000 0.000000 451 | v -0.250000 0.300000 0.000000 452 | v -0.200000 0.300000 0.000000 453 | v -0.150000 0.300000 0.000000 454 | v -0.100000 0.300000 0.000000 455 | v -0.050000 0.300000 0.000000 456 | v 0.000000 0.300000 0.000000 457 | v 0.050000 0.300000 0.000000 458 | v 0.100000 0.300000 0.000000 459 | v 0.150000 0.300000 0.000000 460 | v 0.200000 0.300000 0.000000 461 | v 0.250000 0.300000 0.000000 462 | v 0.300000 0.300000 0.000000 463 | v 0.350000 0.300000 0.000000 464 | v 0.400000 0.300000 0.000000 465 | v 0.450000 0.300000 0.000000 466 | v 0.500000 0.300000 0.000000 467 | v -0.500000 0.350000 0.000000 468 | v -0.450000 0.350000 0.000000 469 | v -0.400000 0.350000 0.000000 470 | v -0.350000 0.350000 0.000000 471 | v -0.300000 0.350000 0.000000 472 | v -0.250000 0.350000 0.000000 473 | v -0.200000 0.350000 0.000000 474 | v -0.150000 0.350000 0.000000 475 | v -0.100000 0.350000 0.000000 476 | v -0.050000 0.350000 0.000000 477 | v 0.000000 0.350000 0.000000 478 | v 0.050000 0.350000 0.000000 479 | v 0.100000 0.350000 0.000000 480 | v 0.150000 0.350000 0.000000 481 | v 0.200000 0.350000 0.000000 482 | v 0.250000 0.350000 0.000000 483 | v 0.300000 0.350000 0.000000 484 | v 0.350000 0.350000 0.000000 485 | v 0.400000 0.350000 0.000000 486 | v 0.450000 0.350000 0.000000 487 | v 0.500000 0.350000 0.000000 488 | v -0.500000 0.400000 0.000000 489 | v -0.450000 0.400000 0.000000 490 | v -0.400000 0.400000 0.000000 491 | v -0.350000 0.400000 0.000000 492 | v -0.300000 0.400000 0.000000 493 | v -0.250000 0.400000 0.000000 494 | v -0.200000 0.400000 0.000000 495 | v -0.150000 0.400000 0.000000 496 | v -0.100000 0.400000 0.000000 497 | v -0.050000 0.400000 0.000000 498 | v 0.000000 0.400000 0.000000 499 | v 0.050000 0.400000 0.000000 500 | v 0.100000 0.400000 0.000000 501 | v 0.150000 0.400000 0.000000 502 | v 0.200000 0.400000 0.000000 503 | v 0.250000 0.400000 0.000000 504 | v 0.300000 0.400000 0.000000 505 | v 0.350000 0.400000 0.000000 506 | v 0.400000 0.400000 0.000000 507 | v 0.450000 0.400000 0.000000 508 | v 0.500000 0.400000 0.000000 509 | v -0.500000 0.450000 0.000000 510 | v -0.450000 0.450000 0.000000 511 | v -0.400000 0.450000 0.000000 512 | v -0.350000 0.450000 0.000000 513 | v -0.300000 0.450000 0.000000 514 | v -0.250000 0.450000 0.000000 515 | v -0.200000 0.450000 0.000000 516 | v -0.150000 0.450000 0.000000 517 | v -0.100000 0.450000 0.000000 518 | v -0.050000 0.450000 0.000000 519 | v 0.000000 0.450000 0.000000 520 | v 0.050000 0.450000 0.000000 521 | v 0.100000 0.450000 0.000000 522 | v 0.150000 0.450000 0.000000 523 | v 0.200000 0.450000 0.000000 524 | v 0.250000 0.450000 0.000000 525 | v 0.300000 0.450000 0.000000 526 | v 0.350000 0.450000 0.000000 527 | v 0.400000 0.450000 0.000000 528 | v 0.450000 0.450000 0.000000 529 | v 0.500000 0.450000 0.000000 530 | v -0.500000 0.500000 0.000000 531 | v -0.450000 0.500000 0.000000 532 | v -0.400000 0.500000 0.000000 533 | v -0.350000 0.500000 0.000000 534 | v -0.300000 0.500000 0.000000 535 | v -0.250000 0.500000 0.000000 536 | v -0.200000 0.500000 0.000000 537 | v -0.150000 0.500000 0.000000 538 | v -0.100000 0.500000 0.000000 539 | v -0.050000 0.500000 0.000000 540 | v 0.000000 0.500000 0.000000 541 | v 0.050000 0.500000 0.000000 542 | v 0.100000 0.500000 0.000000 543 | v 0.150000 0.500000 0.000000 544 | v 0.200000 0.500000 0.000000 545 | v 0.250000 0.500000 0.000000 546 | v 0.300000 0.500000 0.000000 547 | v 0.350000 0.500000 0.000000 548 | v 0.400000 0.500000 0.000000 549 | v 0.450000 0.500000 0.000000 550 | v 0.500000 0.500000 0.000000 551 | v -0.500000 0.550000 0.000000 552 | v -0.450000 0.550000 0.000000 553 | v -0.400000 0.550000 0.000000 554 | v -0.350000 0.550000 0.000000 555 | v -0.300000 0.550000 0.000000 556 | v -0.250000 0.550000 0.000000 557 | v -0.200000 0.550000 0.000000 558 | v -0.150000 0.550000 0.000000 559 | v -0.100000 0.550000 0.000000 560 | v -0.050000 0.550000 0.000000 561 | v 0.000000 0.550000 0.000000 562 | v 0.050000 0.550000 0.000000 563 | v 0.100000 0.550000 0.000000 564 | v 0.150000 0.550000 0.000000 565 | v 0.200000 0.550000 0.000000 566 | v 0.250000 0.550000 0.000000 567 | v 0.300000 0.550000 0.000000 568 | v 0.350000 0.550000 0.000000 569 | v 0.400000 0.550000 0.000000 570 | v 0.450000 0.550000 0.000000 571 | v 0.500000 0.550000 0.000000 572 | v -0.500000 0.600000 0.000000 573 | v -0.450000 0.600000 0.000000 574 | v -0.400000 0.600000 0.000000 575 | v -0.350000 0.600000 0.000000 576 | v -0.300000 0.600000 0.000000 577 | v -0.250000 0.600000 0.000000 578 | v -0.200000 0.600000 0.000000 579 | v -0.150000 0.600000 0.000000 580 | v -0.100000 0.600000 0.000000 581 | v -0.050000 0.600000 0.000000 582 | v 0.000000 0.600000 0.000000 583 | v 0.050000 0.600000 0.000000 584 | v 0.100000 0.600000 0.000000 585 | v 0.150000 0.600000 0.000000 586 | v 0.200000 0.600000 0.000000 587 | v 0.250000 0.600000 0.000000 588 | v 0.300000 0.600000 0.000000 589 | v 0.350000 0.600000 0.000000 590 | v 0.400000 0.600000 0.000000 591 | v 0.450000 0.600000 0.000000 592 | v 0.500000 0.600000 0.000000 593 | v -0.500000 0.650000 0.000000 594 | v -0.450000 0.650000 0.000000 595 | v -0.400000 0.650000 0.000000 596 | v -0.350000 0.650000 0.000000 597 | v -0.300000 0.650000 0.000000 598 | v -0.250000 0.650000 0.000000 599 | v -0.200000 0.650000 0.000000 600 | v -0.150000 0.650000 0.000000 601 | v -0.100000 0.650000 0.000000 602 | v -0.050000 0.650000 0.000000 603 | v 0.000000 0.650000 0.000000 604 | v 0.050000 0.650000 0.000000 605 | v 0.100000 0.650000 0.000000 606 | v 0.150000 0.650000 0.000000 607 | v 0.200000 0.650000 0.000000 608 | v 0.250000 0.650000 0.000000 609 | v 0.300000 0.650000 0.000000 610 | v 0.350000 0.650000 0.000000 611 | v 0.400000 0.650000 0.000000 612 | v 0.450000 0.650000 0.000000 613 | v 0.500000 0.650000 0.000000 614 | v -0.500000 0.700000 0.000000 615 | v -0.450000 0.700000 0.000000 616 | v -0.400000 0.700000 0.000000 617 | v -0.350000 0.700000 0.000000 618 | v -0.300000 0.700000 0.000000 619 | v -0.250000 0.700000 0.000000 620 | v -0.200000 0.700000 0.000000 621 | v -0.150000 0.700000 0.000000 622 | v -0.100000 0.700000 0.000000 623 | v -0.050000 0.700000 0.000000 624 | v 0.000000 0.700000 0.000000 625 | v 0.050000 0.700000 0.000000 626 | v 0.100000 0.700000 0.000000 627 | v 0.150000 0.700000 0.000000 628 | v 0.200000 0.700000 0.000000 629 | v 0.250000 0.700000 0.000000 630 | v 0.300000 0.700000 0.000000 631 | v 0.350000 0.700000 0.000000 632 | v 0.400000 0.700000 0.000000 633 | v 0.450000 0.700000 0.000000 634 | v 0.500000 0.700000 0.000000 635 | v -0.500000 0.750000 0.000000 636 | v -0.450000 0.750000 0.000000 637 | v -0.400000 0.750000 0.000000 638 | v -0.350000 0.750000 0.000000 639 | v -0.300000 0.750000 0.000000 640 | v -0.250000 0.750000 0.000000 641 | v -0.200000 0.750000 0.000000 642 | v -0.150000 0.750000 0.000000 643 | v -0.100000 0.750000 0.000000 644 | v -0.050000 0.750000 0.000000 645 | v 0.000000 0.750000 0.000000 646 | v 0.050000 0.750000 0.000000 647 | v 0.100000 0.750000 0.000000 648 | v 0.150000 0.750000 0.000000 649 | v 0.200000 0.750000 0.000000 650 | v 0.250000 0.750000 0.000000 651 | v 0.300000 0.750000 0.000000 652 | v 0.350000 0.750000 0.000000 653 | v 0.400000 0.750000 0.000000 654 | v 0.450000 0.750000 0.000000 655 | v 0.500000 0.750000 0.000000 656 | vt 0.000000 0.000000 657 | vt 0.050000 0.000000 658 | vt 0.050000 0.033333 659 | vt 0.000000 0.033333 660 | vt 0.100000 0.000000 661 | vt 0.100000 0.033333 662 | vt 0.150000 0.000000 663 | vt 0.150000 0.033333 664 | vt 0.200000 0.000000 665 | vt 0.200000 0.033333 666 | vt 0.250000 0.000000 667 | vt 0.250000 0.033333 668 | vt 0.300000 0.000000 669 | vt 0.300000 0.033333 670 | vt 0.350000 0.000000 671 | vt 0.350000 0.033333 672 | vt 0.400000 0.000000 673 | vt 0.400000 0.033333 674 | vt 0.450000 0.000000 675 | vt 0.450000 0.033333 676 | vt 0.500000 0.000000 677 | vt 0.500000 0.033333 678 | vt 0.550000 0.000000 679 | vt 0.550000 0.033333 680 | vt 0.600000 0.000000 681 | vt 0.600000 0.033333 682 | vt 0.650000 0.000000 683 | vt 0.650000 0.033333 684 | vt 0.700000 0.000000 685 | vt 0.700000 0.033333 686 | vt 0.750000 0.000000 687 | vt 0.750000 0.033333 688 | vt 0.800000 0.000000 689 | vt 0.800000 0.033333 690 | vt 0.850000 0.000000 691 | vt 0.850000 0.033333 692 | vt 0.900000 0.000000 693 | vt 0.900000 0.033333 694 | vt 0.950000 0.000000 695 | vt 0.950000 0.033333 696 | vt 1.000000 0.000000 697 | vt 1.000000 0.033333 698 | vt 0.050000 0.066667 699 | vt 0.000000 0.066667 700 | vt 0.100000 0.066667 701 | vt 0.150000 0.066667 702 | vt 0.200000 0.066667 703 | vt 0.250000 0.066667 704 | vt 0.300000 0.066667 705 | vt 0.350000 0.066667 706 | vt 0.400000 0.066667 707 | vt 0.450000 0.066667 708 | vt 0.500000 0.066667 709 | vt 0.550000 0.066667 710 | vt 0.600000 0.066667 711 | vt 0.650000 0.066667 712 | vt 0.700000 0.066667 713 | vt 0.750000 0.066667 714 | vt 0.800000 0.066667 715 | vt 0.850000 0.066667 716 | vt 0.900000 0.066667 717 | vt 0.950000 0.066667 718 | vt 1.000000 0.066667 719 | vt 0.050000 0.100000 720 | vt 0.000000 0.100000 721 | vt 0.100000 0.100000 722 | vt 0.150000 0.100000 723 | vt 0.200000 0.100000 724 | vt 0.250000 0.100000 725 | vt 0.300000 0.100000 726 | vt 0.350000 0.100000 727 | vt 0.400000 0.100000 728 | vt 0.450000 0.100000 729 | vt 0.500000 0.100000 730 | vt 0.550000 0.100000 731 | vt 0.600000 0.100000 732 | vt 0.650000 0.100000 733 | vt 0.700000 0.100000 734 | vt 0.750000 0.100000 735 | vt 0.800000 0.100000 736 | vt 0.850000 0.100000 737 | vt 0.900000 0.100000 738 | vt 0.950000 0.100000 739 | vt 1.000000 0.100000 740 | vt 0.050000 0.133333 741 | vt 0.000000 0.133333 742 | vt 0.100000 0.133333 743 | vt 0.150000 0.133333 744 | vt 0.200000 0.133333 745 | vt 0.250000 0.133333 746 | vt 0.300000 0.133333 747 | vt 0.350000 0.133333 748 | vt 0.400000 0.133333 749 | vt 0.450000 0.133333 750 | vt 0.500000 0.133333 751 | vt 0.550000 0.133333 752 | vt 0.600000 0.133333 753 | vt 0.650000 0.133333 754 | vt 0.700000 0.133333 755 | vt 0.750000 0.133333 756 | vt 0.800000 0.133333 757 | vt 0.850000 0.133333 758 | vt 0.900000 0.133333 759 | vt 0.950000 0.133333 760 | vt 1.000000 0.133333 761 | vt 0.050000 0.166667 762 | vt 0.000000 0.166667 763 | vt 0.100000 0.166667 764 | vt 0.150000 0.166667 765 | vt 0.200000 0.166667 766 | vt 0.250000 0.166667 767 | vt 0.300000 0.166667 768 | vt 0.350000 0.166667 769 | vt 0.400000 0.166667 770 | vt 0.450000 0.166667 771 | vt 0.500000 0.166667 772 | vt 0.550000 0.166667 773 | vt 0.600000 0.166667 774 | vt 0.650000 0.166667 775 | vt 0.700000 0.166667 776 | vt 0.750000 0.166667 777 | vt 0.800000 0.166667 778 | vt 0.850000 0.166667 779 | vt 0.900000 0.166667 780 | vt 0.950000 0.166667 781 | vt 1.000000 0.166667 782 | vt 0.050000 0.200000 783 | vt 0.000000 0.200000 784 | vt 0.100000 0.200000 785 | vt 0.150000 0.200000 786 | vt 0.200000 0.200000 787 | vt 0.250000 0.200000 788 | vt 0.300000 0.200000 789 | vt 0.350000 0.200000 790 | vt 0.400000 0.200000 791 | vt 0.450000 0.200000 792 | vt 0.500000 0.200000 793 | vt 0.550000 0.200000 794 | vt 0.600000 0.200000 795 | vt 0.650000 0.200000 796 | vt 0.700000 0.200000 797 | vt 0.750000 0.200000 798 | vt 0.800000 0.200000 799 | vt 0.850000 0.200000 800 | vt 0.900000 0.200000 801 | vt 0.950000 0.200000 802 | vt 1.000000 0.200000 803 | vt 0.050000 0.233333 804 | vt 0.000000 0.233333 805 | vt 0.100000 0.233333 806 | vt 0.150000 0.233333 807 | vt 0.200000 0.233333 808 | vt 0.250000 0.233333 809 | vt 0.300000 0.233333 810 | vt 0.350000 0.233333 811 | vt 0.400000 0.233333 812 | vt 0.450000 0.233333 813 | vt 0.500000 0.233333 814 | vt 0.550000 0.233333 815 | vt 0.600000 0.233333 816 | vt 0.650000 0.233333 817 | vt 0.700000 0.233333 818 | vt 0.750000 0.233333 819 | vt 0.800000 0.233333 820 | vt 0.850000 0.233333 821 | vt 0.900000 0.233333 822 | vt 0.950000 0.233333 823 | vt 1.000000 0.233333 824 | vt 0.050000 0.266667 825 | vt 0.000000 0.266667 826 | vt 0.100000 0.266667 827 | vt 0.150000 0.266667 828 | vt 0.200000 0.266667 829 | vt 0.250000 0.266667 830 | vt 0.300000 0.266667 831 | vt 0.350000 0.266667 832 | vt 0.400000 0.266667 833 | vt 0.450000 0.266667 834 | vt 0.500000 0.266667 835 | vt 0.550000 0.266667 836 | vt 0.600000 0.266667 837 | vt 0.650000 0.266667 838 | vt 0.700000 0.266667 839 | vt 0.750000 0.266667 840 | vt 0.800000 0.266667 841 | vt 0.850000 0.266667 842 | vt 0.900000 0.266667 843 | vt 0.950000 0.266667 844 | vt 1.000000 0.266667 845 | vt 0.050000 0.300000 846 | vt 0.000000 0.300000 847 | vt 0.100000 0.300000 848 | vt 0.150000 0.300000 849 | vt 0.200000 0.300000 850 | vt 0.250000 0.300000 851 | vt 0.300000 0.300000 852 | vt 0.350000 0.300000 853 | vt 0.400000 0.300000 854 | vt 0.450000 0.300000 855 | vt 0.500000 0.300000 856 | vt 0.550000 0.300000 857 | vt 0.600000 0.300000 858 | vt 0.650000 0.300000 859 | vt 0.700000 0.300000 860 | vt 0.750000 0.300000 861 | vt 0.800000 0.300000 862 | vt 0.850000 0.300000 863 | vt 0.900000 0.300000 864 | vt 0.950000 0.300000 865 | vt 1.000000 0.300000 866 | vt 0.050000 0.333333 867 | vt 0.000000 0.333333 868 | vt 0.100000 0.333333 869 | vt 0.150000 0.333333 870 | vt 0.200000 0.333333 871 | vt 0.250000 0.333333 872 | vt 0.300000 0.333333 873 | vt 0.350000 0.333333 874 | vt 0.400000 0.333333 875 | vt 0.450000 0.333333 876 | vt 0.500000 0.333333 877 | vt 0.550000 0.333333 878 | vt 0.600000 0.333333 879 | vt 0.650000 0.333333 880 | vt 0.700000 0.333333 881 | vt 0.750000 0.333333 882 | vt 0.800000 0.333333 883 | vt 0.850000 0.333333 884 | vt 0.900000 0.333333 885 | vt 0.950000 0.333333 886 | vt 1.000000 0.333333 887 | vt 0.050000 0.366667 888 | vt 0.000000 0.366667 889 | vt 0.100000 0.366667 890 | vt 0.150000 0.366667 891 | vt 0.200000 0.366667 892 | vt 0.250000 0.366667 893 | vt 0.300000 0.366667 894 | vt 0.350000 0.366667 895 | vt 0.400000 0.366667 896 | vt 0.450000 0.366667 897 | vt 0.500000 0.366667 898 | vt 0.550000 0.366667 899 | vt 0.600000 0.366667 900 | vt 0.650000 0.366667 901 | vt 0.700000 0.366667 902 | vt 0.750000 0.366667 903 | vt 0.800000 0.366667 904 | vt 0.850000 0.366667 905 | vt 0.900000 0.366667 906 | vt 0.950000 0.366667 907 | vt 1.000000 0.366667 908 | vt 0.050000 0.400000 909 | vt 0.000000 0.400000 910 | vt 0.100000 0.400000 911 | vt 0.150000 0.400000 912 | vt 0.200000 0.400000 913 | vt 0.250000 0.400000 914 | vt 0.300000 0.400000 915 | vt 0.350000 0.400000 916 | vt 0.400000 0.400000 917 | vt 0.450000 0.400000 918 | vt 0.500000 0.400000 919 | vt 0.550000 0.400000 920 | vt 0.600000 0.400000 921 | vt 0.650000 0.400000 922 | vt 0.700000 0.400000 923 | vt 0.750000 0.400000 924 | vt 0.800000 0.400000 925 | vt 0.850000 0.400000 926 | vt 0.900000 0.400000 927 | vt 0.950000 0.400000 928 | vt 1.000000 0.400000 929 | vt 0.050000 0.433333 930 | vt 0.000000 0.433333 931 | vt 0.100000 0.433333 932 | vt 0.150000 0.433333 933 | vt 0.200000 0.433333 934 | vt 0.250000 0.433333 935 | vt 0.300000 0.433333 936 | vt 0.350000 0.433333 937 | vt 0.400000 0.433333 938 | vt 0.450000 0.433333 939 | vt 0.500000 0.433333 940 | vt 0.550000 0.433333 941 | vt 0.600000 0.433333 942 | vt 0.650000 0.433333 943 | vt 0.700000 0.433333 944 | vt 0.750000 0.433333 945 | vt 0.800000 0.433333 946 | vt 0.850000 0.433333 947 | vt 0.900000 0.433333 948 | vt 0.950000 0.433333 949 | vt 1.000000 0.433333 950 | vt 0.050000 0.466667 951 | vt 0.000000 0.466667 952 | vt 0.100000 0.466667 953 | vt 0.150000 0.466667 954 | vt 0.200000 0.466667 955 | vt 0.250000 0.466667 956 | vt 0.300000 0.466667 957 | vt 0.350000 0.466667 958 | vt 0.400000 0.466667 959 | vt 0.450000 0.466667 960 | vt 0.500000 0.466667 961 | vt 0.550000 0.466667 962 | vt 0.600000 0.466667 963 | vt 0.650000 0.466667 964 | vt 0.700000 0.466667 965 | vt 0.750000 0.466667 966 | vt 0.800000 0.466667 967 | vt 0.850000 0.466667 968 | vt 0.900000 0.466667 969 | vt 0.950000 0.466667 970 | vt 1.000000 0.466667 971 | vt 0.050000 0.500000 972 | vt 0.000000 0.500000 973 | vt 0.100000 0.500000 974 | vt 0.150000 0.500000 975 | vt 0.200000 0.500000 976 | vt 0.250000 0.500000 977 | vt 0.300000 0.500000 978 | vt 0.350000 0.500000 979 | vt 0.400000 0.500000 980 | vt 0.450000 0.500000 981 | vt 0.500000 0.500000 982 | vt 0.550000 0.500000 983 | vt 0.600000 0.500000 984 | vt 0.650000 0.500000 985 | vt 0.700000 0.500000 986 | vt 0.750000 0.500000 987 | vt 0.800000 0.500000 988 | vt 0.850000 0.500000 989 | vt 0.900000 0.500000 990 | vt 0.950000 0.500000 991 | vt 1.000000 0.500000 992 | vt 0.050000 0.533333 993 | vt 0.000000 0.533333 994 | vt 0.100000 0.533333 995 | vt 0.150000 0.533333 996 | vt 0.200000 0.533333 997 | vt 0.250000 0.533333 998 | vt 0.300000 0.533333 999 | vt 0.350000 0.533333 1000 | vt 0.400000 0.533333 1001 | vt 0.450000 0.533333 1002 | vt 0.500000 0.533333 1003 | vt 0.550000 0.533333 1004 | vt 0.600000 0.533333 1005 | vt 0.650000 0.533333 1006 | vt 0.700000 0.533333 1007 | vt 0.750000 0.533333 1008 | vt 0.800000 0.533333 1009 | vt 0.850000 0.533333 1010 | vt 0.900000 0.533333 1011 | vt 0.950000 0.533333 1012 | vt 1.000000 0.533333 1013 | vt 0.050000 0.566667 1014 | vt 0.000000 0.566667 1015 | vt 0.100000 0.566667 1016 | vt 0.150000 0.566667 1017 | vt 0.200000 0.566667 1018 | vt 0.250000 0.566667 1019 | vt 0.300000 0.566667 1020 | vt 0.350000 0.566667 1021 | vt 0.400000 0.566667 1022 | vt 0.450000 0.566667 1023 | vt 0.500000 0.566667 1024 | vt 0.550000 0.566667 1025 | vt 0.600000 0.566667 1026 | vt 0.650000 0.566667 1027 | vt 0.700000 0.566667 1028 | vt 0.750000 0.566667 1029 | vt 0.800000 0.566667 1030 | vt 0.850000 0.566667 1031 | vt 0.900000 0.566667 1032 | vt 0.950000 0.566667 1033 | vt 1.000000 0.566667 1034 | vt 0.050000 0.600000 1035 | vt 0.000000 0.600000 1036 | vt 0.100000 0.600000 1037 | vt 0.150000 0.600000 1038 | vt 0.200000 0.600000 1039 | vt 0.250000 0.600000 1040 | vt 0.300000 0.600000 1041 | vt 0.350000 0.600000 1042 | vt 0.400000 0.600000 1043 | vt 0.450000 0.600000 1044 | vt 0.500000 0.600000 1045 | vt 0.550000 0.600000 1046 | vt 0.600000 0.600000 1047 | vt 0.650000 0.600000 1048 | vt 0.700000 0.600000 1049 | vt 0.750000 0.600000 1050 | vt 0.800000 0.600000 1051 | vt 0.850000 0.600000 1052 | vt 0.900000 0.600000 1053 | vt 0.950000 0.600000 1054 | vt 1.000000 0.600000 1055 | vt 0.050000 0.633333 1056 | vt 0.000000 0.633333 1057 | vt 0.100000 0.633333 1058 | vt 0.150000 0.633333 1059 | vt 0.200000 0.633333 1060 | vt 0.250000 0.633333 1061 | vt 0.300000 0.633333 1062 | vt 0.350000 0.633333 1063 | vt 0.400000 0.633333 1064 | vt 0.450000 0.633333 1065 | vt 0.500000 0.633333 1066 | vt 0.550000 0.633333 1067 | vt 0.600000 0.633333 1068 | vt 0.650000 0.633333 1069 | vt 0.700000 0.633333 1070 | vt 0.750000 0.633333 1071 | vt 0.800000 0.633333 1072 | vt 0.850000 0.633333 1073 | vt 0.900000 0.633333 1074 | vt 0.950000 0.633333 1075 | vt 1.000000 0.633333 1076 | vt 0.050000 0.666667 1077 | vt 0.000000 0.666667 1078 | vt 0.100000 0.666667 1079 | vt 0.150000 0.666667 1080 | vt 0.200000 0.666667 1081 | vt 0.250000 0.666667 1082 | vt 0.300000 0.666667 1083 | vt 0.350000 0.666667 1084 | vt 0.400000 0.666667 1085 | vt 0.450000 0.666667 1086 | vt 0.500000 0.666667 1087 | vt 0.550000 0.666667 1088 | vt 0.600000 0.666667 1089 | vt 0.650000 0.666667 1090 | vt 0.700000 0.666667 1091 | vt 0.750000 0.666667 1092 | vt 0.800000 0.666667 1093 | vt 0.850000 0.666667 1094 | vt 0.900000 0.666667 1095 | vt 0.950000 0.666667 1096 | vt 1.000000 0.666667 1097 | vt 0.050000 0.700000 1098 | vt 0.000000 0.700000 1099 | vt 0.100000 0.700000 1100 | vt 0.150000 0.700000 1101 | vt 0.200000 0.700000 1102 | vt 0.250000 0.700000 1103 | vt 0.300000 0.700000 1104 | vt 0.350000 0.700000 1105 | vt 0.400000 0.700000 1106 | vt 0.450000 0.700000 1107 | vt 0.500000 0.700000 1108 | vt 0.550000 0.700000 1109 | vt 0.600000 0.700000 1110 | vt 0.650000 0.700000 1111 | vt 0.700000 0.700000 1112 | vt 0.750000 0.700000 1113 | vt 0.800000 0.700000 1114 | vt 0.850000 0.700000 1115 | vt 0.900000 0.700000 1116 | vt 0.950000 0.700000 1117 | vt 1.000000 0.700000 1118 | vt 0.050000 0.733334 1119 | vt 0.000000 0.733334 1120 | vt 0.100000 0.733334 1121 | vt 0.150000 0.733334 1122 | vt 0.200000 0.733334 1123 | vt 0.250000 0.733334 1124 | vt 0.300000 0.733334 1125 | vt 0.350000 0.733334 1126 | vt 0.400000 0.733334 1127 | vt 0.450000 0.733334 1128 | vt 0.500000 0.733334 1129 | vt 0.550000 0.733334 1130 | vt 0.600000 0.733334 1131 | vt 0.650000 0.733334 1132 | vt 0.700000 0.733334 1133 | vt 0.750000 0.733334 1134 | vt 0.800000 0.733334 1135 | vt 0.850000 0.733334 1136 | vt 0.900000 0.733334 1137 | vt 0.950000 0.733334 1138 | vt 1.000000 0.733334 1139 | vt 0.050000 0.766667 1140 | vt 0.000000 0.766667 1141 | vt 0.100000 0.766667 1142 | vt 0.150000 0.766667 1143 | vt 0.200000 0.766667 1144 | vt 0.250000 0.766667 1145 | vt 0.300000 0.766667 1146 | vt 0.350000 0.766667 1147 | vt 0.400000 0.766667 1148 | vt 0.450000 0.766667 1149 | vt 0.500000 0.766667 1150 | vt 0.550000 0.766667 1151 | vt 0.600000 0.766667 1152 | vt 0.650000 0.766667 1153 | vt 0.700000 0.766667 1154 | vt 0.750000 0.766667 1155 | vt 0.800000 0.766667 1156 | vt 0.850000 0.766667 1157 | vt 0.900000 0.766667 1158 | vt 0.950000 0.766667 1159 | vt 1.000000 0.766667 1160 | vt 0.050000 0.800000 1161 | vt 0.000000 0.800000 1162 | vt 0.100000 0.800000 1163 | vt 0.150000 0.800000 1164 | vt 0.200000 0.800000 1165 | vt 0.250000 0.800000 1166 | vt 0.300000 0.800000 1167 | vt 0.350000 0.800000 1168 | vt 0.400000 0.800000 1169 | vt 0.450000 0.800000 1170 | vt 0.500000 0.800000 1171 | vt 0.550000 0.800000 1172 | vt 0.600000 0.800000 1173 | vt 0.650000 0.800000 1174 | vt 0.700000 0.800000 1175 | vt 0.750000 0.800000 1176 | vt 0.800000 0.800000 1177 | vt 0.850000 0.800000 1178 | vt 0.900000 0.800000 1179 | vt 0.950000 0.800000 1180 | vt 1.000000 0.800000 1181 | vt 0.050000 0.833334 1182 | vt 0.000000 0.833334 1183 | vt 0.100000 0.833334 1184 | vt 0.150000 0.833334 1185 | vt 0.200000 0.833334 1186 | vt 0.250000 0.833334 1187 | vt 0.300000 0.833334 1188 | vt 0.350000 0.833334 1189 | vt 0.400000 0.833334 1190 | vt 0.450000 0.833334 1191 | vt 0.500000 0.833334 1192 | vt 0.550000 0.833334 1193 | vt 0.600000 0.833334 1194 | vt 0.650000 0.833334 1195 | vt 0.700000 0.833334 1196 | vt 0.750000 0.833334 1197 | vt 0.800000 0.833334 1198 | vt 0.850000 0.833334 1199 | vt 0.900000 0.833334 1200 | vt 0.950000 0.833334 1201 | vt 1.000000 0.833334 1202 | vt 0.050000 0.866667 1203 | vt 0.000000 0.866667 1204 | vt 0.100000 0.866667 1205 | vt 0.150000 0.866667 1206 | vt 0.200000 0.866667 1207 | vt 0.250000 0.866667 1208 | vt 0.300000 0.866667 1209 | vt 0.350000 0.866667 1210 | vt 0.400000 0.866667 1211 | vt 0.450000 0.866667 1212 | vt 0.500000 0.866667 1213 | vt 0.550000 0.866667 1214 | vt 0.600000 0.866667 1215 | vt 0.650000 0.866667 1216 | vt 0.700000 0.866667 1217 | vt 0.750000 0.866667 1218 | vt 0.800000 0.866667 1219 | vt 0.850000 0.866667 1220 | vt 0.900000 0.866667 1221 | vt 0.950000 0.866667 1222 | vt 1.000000 0.866667 1223 | vt 0.050000 0.900000 1224 | vt 0.000000 0.900000 1225 | vt 0.100000 0.900000 1226 | vt 0.150000 0.900000 1227 | vt 0.200000 0.900000 1228 | vt 0.250000 0.900000 1229 | vt 0.300000 0.900000 1230 | vt 0.350000 0.900000 1231 | vt 0.400000 0.900000 1232 | vt 0.450000 0.900000 1233 | vt 0.500000 0.900000 1234 | vt 0.550000 0.900000 1235 | vt 0.600000 0.900000 1236 | vt 0.650000 0.900000 1237 | vt 0.700000 0.900000 1238 | vt 0.750000 0.900000 1239 | vt 0.800000 0.900000 1240 | vt 0.850000 0.900000 1241 | vt 0.900000 0.900000 1242 | vt 0.950000 0.900000 1243 | vt 1.000000 0.900000 1244 | vt 0.050000 0.933334 1245 | vt 0.000000 0.933334 1246 | vt 0.100000 0.933334 1247 | vt 0.150000 0.933334 1248 | vt 0.200000 0.933334 1249 | vt 0.250000 0.933334 1250 | vt 0.300000 0.933334 1251 | vt 0.350000 0.933334 1252 | vt 0.400000 0.933334 1253 | vt 0.450000 0.933334 1254 | vt 0.500000 0.933334 1255 | vt 0.550000 0.933334 1256 | vt 0.600000 0.933334 1257 | vt 0.650000 0.933334 1258 | vt 0.700000 0.933334 1259 | vt 0.750000 0.933334 1260 | vt 0.800000 0.933334 1261 | vt 0.850000 0.933334 1262 | vt 0.900000 0.933334 1263 | vt 0.950000 0.933334 1264 | vt 1.000000 0.933334 1265 | vt 0.050000 0.966667 1266 | vt 0.000000 0.966667 1267 | vt 0.100000 0.966667 1268 | vt 0.150000 0.966667 1269 | vt 0.200000 0.966667 1270 | vt 0.250000 0.966667 1271 | vt 0.300000 0.966667 1272 | vt 0.350000 0.966667 1273 | vt 0.400000 0.966667 1274 | vt 0.450000 0.966667 1275 | vt 0.500000 0.966667 1276 | vt 0.550000 0.966667 1277 | vt 0.600000 0.966667 1278 | vt 0.650000 0.966667 1279 | vt 0.700000 0.966667 1280 | vt 0.750000 0.966667 1281 | vt 0.800000 0.966667 1282 | vt 0.850000 0.966667 1283 | vt 0.900000 0.966667 1284 | vt 0.950000 0.966667 1285 | vt 1.000000 0.966667 1286 | vt 0.050000 1.000000 1287 | vt 0.000000 1.000000 1288 | vt 0.100000 1.000000 1289 | vt 0.150000 1.000000 1290 | vt 0.200000 1.000000 1291 | vt 0.250000 1.000000 1292 | vt 0.300000 1.000000 1293 | vt 0.350000 1.000000 1294 | vt 0.400000 1.000000 1295 | vt 0.450000 1.000000 1296 | vt 0.500000 1.000000 1297 | vt 0.550000 1.000000 1298 | vt 0.600000 1.000000 1299 | vt 0.650000 1.000000 1300 | vt 0.700000 1.000000 1301 | vt 0.750000 1.000000 1302 | vt 0.800000 1.000000 1303 | vt 0.850000 1.000000 1304 | vt 0.900000 1.000000 1305 | vt 0.950000 1.000000 1306 | vt 1.000000 1.000000 1307 | vn 0.0000 -0.0000 1.0000 1308 | usemtl None 1309 | s off 1310 | f 1/1/1 2/2/1 23/3/1 22/4/1 1311 | f 2/2/1 3/5/1 24/6/1 23/3/1 1312 | f 3/5/1 4/7/1 25/8/1 24/6/1 1313 | f 4/7/1 5/9/1 26/10/1 25/8/1 1314 | f 5/9/1 6/11/1 27/12/1 26/10/1 1315 | f 6/11/1 7/13/1 28/14/1 27/12/1 1316 | f 7/13/1 8/15/1 29/16/1 28/14/1 1317 | f 8/15/1 9/17/1 30/18/1 29/16/1 1318 | f 9/17/1 10/19/1 31/20/1 30/18/1 1319 | f 10/19/1 11/21/1 32/22/1 31/20/1 1320 | f 11/21/1 12/23/1 33/24/1 32/22/1 1321 | f 12/23/1 13/25/1 34/26/1 33/24/1 1322 | f 13/25/1 14/27/1 35/28/1 34/26/1 1323 | f 14/27/1 15/29/1 36/30/1 35/28/1 1324 | f 15/29/1 16/31/1 37/32/1 36/30/1 1325 | f 16/31/1 17/33/1 38/34/1 37/32/1 1326 | f 17/33/1 18/35/1 39/36/1 38/34/1 1327 | f 18/35/1 19/37/1 40/38/1 39/36/1 1328 | f 19/37/1 20/39/1 41/40/1 40/38/1 1329 | f 20/39/1 21/41/1 42/42/1 41/40/1 1330 | f 22/4/1 23/3/1 44/43/1 43/44/1 1331 | f 23/3/1 24/6/1 45/45/1 44/43/1 1332 | f 24/6/1 25/8/1 46/46/1 45/45/1 1333 | f 25/8/1 26/10/1 47/47/1 46/46/1 1334 | f 26/10/1 27/12/1 48/48/1 47/47/1 1335 | f 27/12/1 28/14/1 49/49/1 48/48/1 1336 | f 28/14/1 29/16/1 50/50/1 49/49/1 1337 | f 29/16/1 30/18/1 51/51/1 50/50/1 1338 | f 30/18/1 31/20/1 52/52/1 51/51/1 1339 | f 31/20/1 32/22/1 53/53/1 52/52/1 1340 | f 32/22/1 33/24/1 54/54/1 53/53/1 1341 | f 33/24/1 34/26/1 55/55/1 54/54/1 1342 | f 34/26/1 35/28/1 56/56/1 55/55/1 1343 | f 35/28/1 36/30/1 57/57/1 56/56/1 1344 | f 36/30/1 37/32/1 58/58/1 57/57/1 1345 | f 37/32/1 38/34/1 59/59/1 58/58/1 1346 | f 38/34/1 39/36/1 60/60/1 59/59/1 1347 | f 39/36/1 40/38/1 61/61/1 60/60/1 1348 | f 40/38/1 41/40/1 62/62/1 61/61/1 1349 | f 41/40/1 42/42/1 63/63/1 62/62/1 1350 | f 43/44/1 44/43/1 65/64/1 64/65/1 1351 | f 44/43/1 45/45/1 66/66/1 65/64/1 1352 | f 45/45/1 46/46/1 67/67/1 66/66/1 1353 | f 46/46/1 47/47/1 68/68/1 67/67/1 1354 | f 47/47/1 48/48/1 69/69/1 68/68/1 1355 | f 48/48/1 49/49/1 70/70/1 69/69/1 1356 | f 49/49/1 50/50/1 71/71/1 70/70/1 1357 | f 50/50/1 51/51/1 72/72/1 71/71/1 1358 | f 51/51/1 52/52/1 73/73/1 72/72/1 1359 | f 52/52/1 53/53/1 74/74/1 73/73/1 1360 | f 53/53/1 54/54/1 75/75/1 74/74/1 1361 | f 54/54/1 55/55/1 76/76/1 75/75/1 1362 | f 55/55/1 56/56/1 77/77/1 76/76/1 1363 | f 56/56/1 57/57/1 78/78/1 77/77/1 1364 | f 57/57/1 58/58/1 79/79/1 78/78/1 1365 | f 58/58/1 59/59/1 80/80/1 79/79/1 1366 | f 59/59/1 60/60/1 81/81/1 80/80/1 1367 | f 60/60/1 61/61/1 82/82/1 81/81/1 1368 | f 61/61/1 62/62/1 83/83/1 82/82/1 1369 | f 62/62/1 63/63/1 84/84/1 83/83/1 1370 | f 64/65/1 65/64/1 86/85/1 85/86/1 1371 | f 65/64/1 66/66/1 87/87/1 86/85/1 1372 | f 66/66/1 67/67/1 88/88/1 87/87/1 1373 | f 67/67/1 68/68/1 89/89/1 88/88/1 1374 | f 68/68/1 69/69/1 90/90/1 89/89/1 1375 | f 69/69/1 70/70/1 91/91/1 90/90/1 1376 | f 70/70/1 71/71/1 92/92/1 91/91/1 1377 | f 71/71/1 72/72/1 93/93/1 92/92/1 1378 | f 72/72/1 73/73/1 94/94/1 93/93/1 1379 | f 73/73/1 74/74/1 95/95/1 94/94/1 1380 | f 74/74/1 75/75/1 96/96/1 95/95/1 1381 | f 75/75/1 76/76/1 97/97/1 96/96/1 1382 | f 76/76/1 77/77/1 98/98/1 97/97/1 1383 | f 77/77/1 78/78/1 99/99/1 98/98/1 1384 | f 78/78/1 79/79/1 100/100/1 99/99/1 1385 | f 79/79/1 80/80/1 101/101/1 100/100/1 1386 | f 80/80/1 81/81/1 102/102/1 101/101/1 1387 | f 81/81/1 82/82/1 103/103/1 102/102/1 1388 | f 82/82/1 83/83/1 104/104/1 103/103/1 1389 | f 83/83/1 84/84/1 105/105/1 104/104/1 1390 | f 85/86/1 86/85/1 107/106/1 106/107/1 1391 | f 86/85/1 87/87/1 108/108/1 107/106/1 1392 | f 87/87/1 88/88/1 109/109/1 108/108/1 1393 | f 88/88/1 89/89/1 110/110/1 109/109/1 1394 | f 89/89/1 90/90/1 111/111/1 110/110/1 1395 | f 90/90/1 91/91/1 112/112/1 111/111/1 1396 | f 91/91/1 92/92/1 113/113/1 112/112/1 1397 | f 92/92/1 93/93/1 114/114/1 113/113/1 1398 | f 93/93/1 94/94/1 115/115/1 114/114/1 1399 | f 94/94/1 95/95/1 116/116/1 115/115/1 1400 | f 95/95/1 96/96/1 117/117/1 116/116/1 1401 | f 96/96/1 97/97/1 118/118/1 117/117/1 1402 | f 97/97/1 98/98/1 119/119/1 118/118/1 1403 | f 98/98/1 99/99/1 120/120/1 119/119/1 1404 | f 99/99/1 100/100/1 121/121/1 120/120/1 1405 | f 100/100/1 101/101/1 122/122/1 121/121/1 1406 | f 101/101/1 102/102/1 123/123/1 122/122/1 1407 | f 102/102/1 103/103/1 124/124/1 123/123/1 1408 | f 103/103/1 104/104/1 125/125/1 124/124/1 1409 | f 104/104/1 105/105/1 126/126/1 125/125/1 1410 | f 106/107/1 107/106/1 128/127/1 127/128/1 1411 | f 107/106/1 108/108/1 129/129/1 128/127/1 1412 | f 108/108/1 109/109/1 130/130/1 129/129/1 1413 | f 109/109/1 110/110/1 131/131/1 130/130/1 1414 | f 110/110/1 111/111/1 132/132/1 131/131/1 1415 | f 111/111/1 112/112/1 133/133/1 132/132/1 1416 | f 112/112/1 113/113/1 134/134/1 133/133/1 1417 | f 113/113/1 114/114/1 135/135/1 134/134/1 1418 | f 114/114/1 115/115/1 136/136/1 135/135/1 1419 | f 115/115/1 116/116/1 137/137/1 136/136/1 1420 | f 116/116/1 117/117/1 138/138/1 137/137/1 1421 | f 117/117/1 118/118/1 139/139/1 138/138/1 1422 | f 118/118/1 119/119/1 140/140/1 139/139/1 1423 | f 119/119/1 120/120/1 141/141/1 140/140/1 1424 | f 120/120/1 121/121/1 142/142/1 141/141/1 1425 | f 121/121/1 122/122/1 143/143/1 142/142/1 1426 | f 122/122/1 123/123/1 144/144/1 143/143/1 1427 | f 123/123/1 124/124/1 145/145/1 144/144/1 1428 | f 124/124/1 125/125/1 146/146/1 145/145/1 1429 | f 125/125/1 126/126/1 147/147/1 146/146/1 1430 | f 127/128/1 128/127/1 149/148/1 148/149/1 1431 | f 128/127/1 129/129/1 150/150/1 149/148/1 1432 | f 129/129/1 130/130/1 151/151/1 150/150/1 1433 | f 130/130/1 131/131/1 152/152/1 151/151/1 1434 | f 131/131/1 132/132/1 153/153/1 152/152/1 1435 | f 132/132/1 133/133/1 154/154/1 153/153/1 1436 | f 133/133/1 134/134/1 155/155/1 154/154/1 1437 | f 134/134/1 135/135/1 156/156/1 155/155/1 1438 | f 135/135/1 136/136/1 157/157/1 156/156/1 1439 | f 136/136/1 137/137/1 158/158/1 157/157/1 1440 | f 137/137/1 138/138/1 159/159/1 158/158/1 1441 | f 138/138/1 139/139/1 160/160/1 159/159/1 1442 | f 139/139/1 140/140/1 161/161/1 160/160/1 1443 | f 140/140/1 141/141/1 162/162/1 161/161/1 1444 | f 141/141/1 142/142/1 163/163/1 162/162/1 1445 | f 142/142/1 143/143/1 164/164/1 163/163/1 1446 | f 143/143/1 144/144/1 165/165/1 164/164/1 1447 | f 144/144/1 145/145/1 166/166/1 165/165/1 1448 | f 145/145/1 146/146/1 167/167/1 166/166/1 1449 | f 146/146/1 147/147/1 168/168/1 167/167/1 1450 | f 148/149/1 149/148/1 170/169/1 169/170/1 1451 | f 149/148/1 150/150/1 171/171/1 170/169/1 1452 | f 150/150/1 151/151/1 172/172/1 171/171/1 1453 | f 151/151/1 152/152/1 173/173/1 172/172/1 1454 | f 152/152/1 153/153/1 174/174/1 173/173/1 1455 | f 153/153/1 154/154/1 175/175/1 174/174/1 1456 | f 154/154/1 155/155/1 176/176/1 175/175/1 1457 | f 155/155/1 156/156/1 177/177/1 176/176/1 1458 | f 156/156/1 157/157/1 178/178/1 177/177/1 1459 | f 157/157/1 158/158/1 179/179/1 178/178/1 1460 | f 158/158/1 159/159/1 180/180/1 179/179/1 1461 | f 159/159/1 160/160/1 181/181/1 180/180/1 1462 | f 160/160/1 161/161/1 182/182/1 181/181/1 1463 | f 161/161/1 162/162/1 183/183/1 182/182/1 1464 | f 162/162/1 163/163/1 184/184/1 183/183/1 1465 | f 163/163/1 164/164/1 185/185/1 184/184/1 1466 | f 164/164/1 165/165/1 186/186/1 185/185/1 1467 | f 165/165/1 166/166/1 187/187/1 186/186/1 1468 | f 166/166/1 167/167/1 188/188/1 187/187/1 1469 | f 167/167/1 168/168/1 189/189/1 188/188/1 1470 | f 169/170/1 170/169/1 191/190/1 190/191/1 1471 | f 170/169/1 171/171/1 192/192/1 191/190/1 1472 | f 171/171/1 172/172/1 193/193/1 192/192/1 1473 | f 172/172/1 173/173/1 194/194/1 193/193/1 1474 | f 173/173/1 174/174/1 195/195/1 194/194/1 1475 | f 174/174/1 175/175/1 196/196/1 195/195/1 1476 | f 175/175/1 176/176/1 197/197/1 196/196/1 1477 | f 176/176/1 177/177/1 198/198/1 197/197/1 1478 | f 177/177/1 178/178/1 199/199/1 198/198/1 1479 | f 178/178/1 179/179/1 200/200/1 199/199/1 1480 | f 179/179/1 180/180/1 201/201/1 200/200/1 1481 | f 180/180/1 181/181/1 202/202/1 201/201/1 1482 | f 181/181/1 182/182/1 203/203/1 202/202/1 1483 | f 182/182/1 183/183/1 204/204/1 203/203/1 1484 | f 183/183/1 184/184/1 205/205/1 204/204/1 1485 | f 184/184/1 185/185/1 206/206/1 205/205/1 1486 | f 185/185/1 186/186/1 207/207/1 206/206/1 1487 | f 186/186/1 187/187/1 208/208/1 207/207/1 1488 | f 187/187/1 188/188/1 209/209/1 208/208/1 1489 | f 188/188/1 189/189/1 210/210/1 209/209/1 1490 | f 190/191/1 191/190/1 212/211/1 211/212/1 1491 | f 191/190/1 192/192/1 213/213/1 212/211/1 1492 | f 192/192/1 193/193/1 214/214/1 213/213/1 1493 | f 193/193/1 194/194/1 215/215/1 214/214/1 1494 | f 194/194/1 195/195/1 216/216/1 215/215/1 1495 | f 195/195/1 196/196/1 217/217/1 216/216/1 1496 | f 196/196/1 197/197/1 218/218/1 217/217/1 1497 | f 197/197/1 198/198/1 219/219/1 218/218/1 1498 | f 198/198/1 199/199/1 220/220/1 219/219/1 1499 | f 199/199/1 200/200/1 221/221/1 220/220/1 1500 | f 200/200/1 201/201/1 222/222/1 221/221/1 1501 | f 201/201/1 202/202/1 223/223/1 222/222/1 1502 | f 202/202/1 203/203/1 224/224/1 223/223/1 1503 | f 203/203/1 204/204/1 225/225/1 224/224/1 1504 | f 204/204/1 205/205/1 226/226/1 225/225/1 1505 | f 205/205/1 206/206/1 227/227/1 226/226/1 1506 | f 206/206/1 207/207/1 228/228/1 227/227/1 1507 | f 207/207/1 208/208/1 229/229/1 228/228/1 1508 | f 208/208/1 209/209/1 230/230/1 229/229/1 1509 | f 209/209/1 210/210/1 231/231/1 230/230/1 1510 | f 211/212/1 212/211/1 233/232/1 232/233/1 1511 | f 212/211/1 213/213/1 234/234/1 233/232/1 1512 | f 213/213/1 214/214/1 235/235/1 234/234/1 1513 | f 214/214/1 215/215/1 236/236/1 235/235/1 1514 | f 215/215/1 216/216/1 237/237/1 236/236/1 1515 | f 216/216/1 217/217/1 238/238/1 237/237/1 1516 | f 217/217/1 218/218/1 239/239/1 238/238/1 1517 | f 218/218/1 219/219/1 240/240/1 239/239/1 1518 | f 219/219/1 220/220/1 241/241/1 240/240/1 1519 | f 220/220/1 221/221/1 242/242/1 241/241/1 1520 | f 221/221/1 222/222/1 243/243/1 242/242/1 1521 | f 222/222/1 223/223/1 244/244/1 243/243/1 1522 | f 223/223/1 224/224/1 245/245/1 244/244/1 1523 | f 224/224/1 225/225/1 246/246/1 245/245/1 1524 | f 225/225/1 226/226/1 247/247/1 246/246/1 1525 | f 226/226/1 227/227/1 248/248/1 247/247/1 1526 | f 227/227/1 228/228/1 249/249/1 248/248/1 1527 | f 228/228/1 229/229/1 250/250/1 249/249/1 1528 | f 229/229/1 230/230/1 251/251/1 250/250/1 1529 | f 230/230/1 231/231/1 252/252/1 251/251/1 1530 | f 232/233/1 233/232/1 254/253/1 253/254/1 1531 | f 233/232/1 234/234/1 255/255/1 254/253/1 1532 | f 234/234/1 235/235/1 256/256/1 255/255/1 1533 | f 235/235/1 236/236/1 257/257/1 256/256/1 1534 | f 236/236/1 237/237/1 258/258/1 257/257/1 1535 | f 237/237/1 238/238/1 259/259/1 258/258/1 1536 | f 238/238/1 239/239/1 260/260/1 259/259/1 1537 | f 239/239/1 240/240/1 261/261/1 260/260/1 1538 | f 240/240/1 241/241/1 262/262/1 261/261/1 1539 | f 241/241/1 242/242/1 263/263/1 262/262/1 1540 | f 242/242/1 243/243/1 264/264/1 263/263/1 1541 | f 243/243/1 244/244/1 265/265/1 264/264/1 1542 | f 244/244/1 245/245/1 266/266/1 265/265/1 1543 | f 245/245/1 246/246/1 267/267/1 266/266/1 1544 | f 246/246/1 247/247/1 268/268/1 267/267/1 1545 | f 247/247/1 248/248/1 269/269/1 268/268/1 1546 | f 248/248/1 249/249/1 270/270/1 269/269/1 1547 | f 249/249/1 250/250/1 271/271/1 270/270/1 1548 | f 250/250/1 251/251/1 272/272/1 271/271/1 1549 | f 251/251/1 252/252/1 273/273/1 272/272/1 1550 | f 253/254/1 254/253/1 275/274/1 274/275/1 1551 | f 254/253/1 255/255/1 276/276/1 275/274/1 1552 | f 255/255/1 256/256/1 277/277/1 276/276/1 1553 | f 256/256/1 257/257/1 278/278/1 277/277/1 1554 | f 257/257/1 258/258/1 279/279/1 278/278/1 1555 | f 258/258/1 259/259/1 280/280/1 279/279/1 1556 | f 259/259/1 260/260/1 281/281/1 280/280/1 1557 | f 260/260/1 261/261/1 282/282/1 281/281/1 1558 | f 261/261/1 262/262/1 283/283/1 282/282/1 1559 | f 262/262/1 263/263/1 284/284/1 283/283/1 1560 | f 263/263/1 264/264/1 285/285/1 284/284/1 1561 | f 264/264/1 265/265/1 286/286/1 285/285/1 1562 | f 265/265/1 266/266/1 287/287/1 286/286/1 1563 | f 266/266/1 267/267/1 288/288/1 287/287/1 1564 | f 267/267/1 268/268/1 289/289/1 288/288/1 1565 | f 268/268/1 269/269/1 290/290/1 289/289/1 1566 | f 269/269/1 270/270/1 291/291/1 290/290/1 1567 | f 270/270/1 271/271/1 292/292/1 291/291/1 1568 | f 271/271/1 272/272/1 293/293/1 292/292/1 1569 | f 272/272/1 273/273/1 294/294/1 293/293/1 1570 | f 274/275/1 275/274/1 296/295/1 295/296/1 1571 | f 275/274/1 276/276/1 297/297/1 296/295/1 1572 | f 276/276/1 277/277/1 298/298/1 297/297/1 1573 | f 277/277/1 278/278/1 299/299/1 298/298/1 1574 | f 278/278/1 279/279/1 300/300/1 299/299/1 1575 | f 279/279/1 280/280/1 301/301/1 300/300/1 1576 | f 280/280/1 281/281/1 302/302/1 301/301/1 1577 | f 281/281/1 282/282/1 303/303/1 302/302/1 1578 | f 282/282/1 283/283/1 304/304/1 303/303/1 1579 | f 283/283/1 284/284/1 305/305/1 304/304/1 1580 | f 284/284/1 285/285/1 306/306/1 305/305/1 1581 | f 285/285/1 286/286/1 307/307/1 306/306/1 1582 | f 286/286/1 287/287/1 308/308/1 307/307/1 1583 | f 287/287/1 288/288/1 309/309/1 308/308/1 1584 | f 288/288/1 289/289/1 310/310/1 309/309/1 1585 | f 289/289/1 290/290/1 311/311/1 310/310/1 1586 | f 290/290/1 291/291/1 312/312/1 311/311/1 1587 | f 291/291/1 292/292/1 313/313/1 312/312/1 1588 | f 292/292/1 293/293/1 314/314/1 313/313/1 1589 | f 293/293/1 294/294/1 315/315/1 314/314/1 1590 | f 295/296/1 296/295/1 317/316/1 316/317/1 1591 | f 296/295/1 297/297/1 318/318/1 317/316/1 1592 | f 297/297/1 298/298/1 319/319/1 318/318/1 1593 | f 298/298/1 299/299/1 320/320/1 319/319/1 1594 | f 299/299/1 300/300/1 321/321/1 320/320/1 1595 | f 300/300/1 301/301/1 322/322/1 321/321/1 1596 | f 301/301/1 302/302/1 323/323/1 322/322/1 1597 | f 302/302/1 303/303/1 324/324/1 323/323/1 1598 | f 303/303/1 304/304/1 325/325/1 324/324/1 1599 | f 304/304/1 305/305/1 326/326/1 325/325/1 1600 | f 305/305/1 306/306/1 327/327/1 326/326/1 1601 | f 306/306/1 307/307/1 328/328/1 327/327/1 1602 | f 307/307/1 308/308/1 329/329/1 328/328/1 1603 | f 308/308/1 309/309/1 330/330/1 329/329/1 1604 | f 309/309/1 310/310/1 331/331/1 330/330/1 1605 | f 310/310/1 311/311/1 332/332/1 331/331/1 1606 | f 311/311/1 312/312/1 333/333/1 332/332/1 1607 | f 312/312/1 313/313/1 334/334/1 333/333/1 1608 | f 313/313/1 314/314/1 335/335/1 334/334/1 1609 | f 314/314/1 315/315/1 336/336/1 335/335/1 1610 | f 316/317/1 317/316/1 338/337/1 337/338/1 1611 | f 317/316/1 318/318/1 339/339/1 338/337/1 1612 | f 318/318/1 319/319/1 340/340/1 339/339/1 1613 | f 319/319/1 320/320/1 341/341/1 340/340/1 1614 | f 320/320/1 321/321/1 342/342/1 341/341/1 1615 | f 321/321/1 322/322/1 343/343/1 342/342/1 1616 | f 322/322/1 323/323/1 344/344/1 343/343/1 1617 | f 323/323/1 324/324/1 345/345/1 344/344/1 1618 | f 324/324/1 325/325/1 346/346/1 345/345/1 1619 | f 325/325/1 326/326/1 347/347/1 346/346/1 1620 | f 326/326/1 327/327/1 348/348/1 347/347/1 1621 | f 327/327/1 328/328/1 349/349/1 348/348/1 1622 | f 328/328/1 329/329/1 350/350/1 349/349/1 1623 | f 329/329/1 330/330/1 351/351/1 350/350/1 1624 | f 330/330/1 331/331/1 352/352/1 351/351/1 1625 | f 331/331/1 332/332/1 353/353/1 352/352/1 1626 | f 332/332/1 333/333/1 354/354/1 353/353/1 1627 | f 333/333/1 334/334/1 355/355/1 354/354/1 1628 | f 334/334/1 335/335/1 356/356/1 355/355/1 1629 | f 335/335/1 336/336/1 357/357/1 356/356/1 1630 | f 337/338/1 338/337/1 359/358/1 358/359/1 1631 | f 338/337/1 339/339/1 360/360/1 359/358/1 1632 | f 339/339/1 340/340/1 361/361/1 360/360/1 1633 | f 340/340/1 341/341/1 362/362/1 361/361/1 1634 | f 341/341/1 342/342/1 363/363/1 362/362/1 1635 | f 342/342/1 343/343/1 364/364/1 363/363/1 1636 | f 343/343/1 344/344/1 365/365/1 364/364/1 1637 | f 344/344/1 345/345/1 366/366/1 365/365/1 1638 | f 345/345/1 346/346/1 367/367/1 366/366/1 1639 | f 346/346/1 347/347/1 368/368/1 367/367/1 1640 | f 347/347/1 348/348/1 369/369/1 368/368/1 1641 | f 348/348/1 349/349/1 370/370/1 369/369/1 1642 | f 349/349/1 350/350/1 371/371/1 370/370/1 1643 | f 350/350/1 351/351/1 372/372/1 371/371/1 1644 | f 351/351/1 352/352/1 373/373/1 372/372/1 1645 | f 352/352/1 353/353/1 374/374/1 373/373/1 1646 | f 353/353/1 354/354/1 375/375/1 374/374/1 1647 | f 354/354/1 355/355/1 376/376/1 375/375/1 1648 | f 355/355/1 356/356/1 377/377/1 376/376/1 1649 | f 356/356/1 357/357/1 378/378/1 377/377/1 1650 | f 358/359/1 359/358/1 380/379/1 379/380/1 1651 | f 359/358/1 360/360/1 381/381/1 380/379/1 1652 | f 360/360/1 361/361/1 382/382/1 381/381/1 1653 | f 361/361/1 362/362/1 383/383/1 382/382/1 1654 | f 362/362/1 363/363/1 384/384/1 383/383/1 1655 | f 363/363/1 364/364/1 385/385/1 384/384/1 1656 | f 364/364/1 365/365/1 386/386/1 385/385/1 1657 | f 365/365/1 366/366/1 387/387/1 386/386/1 1658 | f 366/366/1 367/367/1 388/388/1 387/387/1 1659 | f 367/367/1 368/368/1 389/389/1 388/388/1 1660 | f 368/368/1 369/369/1 390/390/1 389/389/1 1661 | f 369/369/1 370/370/1 391/391/1 390/390/1 1662 | f 370/370/1 371/371/1 392/392/1 391/391/1 1663 | f 371/371/1 372/372/1 393/393/1 392/392/1 1664 | f 372/372/1 373/373/1 394/394/1 393/393/1 1665 | f 373/373/1 374/374/1 395/395/1 394/394/1 1666 | f 374/374/1 375/375/1 396/396/1 395/395/1 1667 | f 375/375/1 376/376/1 397/397/1 396/396/1 1668 | f 376/376/1 377/377/1 398/398/1 397/397/1 1669 | f 377/377/1 378/378/1 399/399/1 398/398/1 1670 | f 379/380/1 380/379/1 401/400/1 400/401/1 1671 | f 380/379/1 381/381/1 402/402/1 401/400/1 1672 | f 381/381/1 382/382/1 403/403/1 402/402/1 1673 | f 382/382/1 383/383/1 404/404/1 403/403/1 1674 | f 383/383/1 384/384/1 405/405/1 404/404/1 1675 | f 384/384/1 385/385/1 406/406/1 405/405/1 1676 | f 385/385/1 386/386/1 407/407/1 406/406/1 1677 | f 386/386/1 387/387/1 408/408/1 407/407/1 1678 | f 387/387/1 388/388/1 409/409/1 408/408/1 1679 | f 388/388/1 389/389/1 410/410/1 409/409/1 1680 | f 389/389/1 390/390/1 411/411/1 410/410/1 1681 | f 390/390/1 391/391/1 412/412/1 411/411/1 1682 | f 391/391/1 392/392/1 413/413/1 412/412/1 1683 | f 392/392/1 393/393/1 414/414/1 413/413/1 1684 | f 393/393/1 394/394/1 415/415/1 414/414/1 1685 | f 394/394/1 395/395/1 416/416/1 415/415/1 1686 | f 395/395/1 396/396/1 417/417/1 416/416/1 1687 | f 396/396/1 397/397/1 418/418/1 417/417/1 1688 | f 397/397/1 398/398/1 419/419/1 418/418/1 1689 | f 398/398/1 399/399/1 420/420/1 419/419/1 1690 | f 400/401/1 401/400/1 422/421/1 421/422/1 1691 | f 401/400/1 402/402/1 423/423/1 422/421/1 1692 | f 402/402/1 403/403/1 424/424/1 423/423/1 1693 | f 403/403/1 404/404/1 425/425/1 424/424/1 1694 | f 404/404/1 405/405/1 426/426/1 425/425/1 1695 | f 405/405/1 406/406/1 427/427/1 426/426/1 1696 | f 406/406/1 407/407/1 428/428/1 427/427/1 1697 | f 407/407/1 408/408/1 429/429/1 428/428/1 1698 | f 408/408/1 409/409/1 430/430/1 429/429/1 1699 | f 409/409/1 410/410/1 431/431/1 430/430/1 1700 | f 410/410/1 411/411/1 432/432/1 431/431/1 1701 | f 411/411/1 412/412/1 433/433/1 432/432/1 1702 | f 412/412/1 413/413/1 434/434/1 433/433/1 1703 | f 413/413/1 414/414/1 435/435/1 434/434/1 1704 | f 414/414/1 415/415/1 436/436/1 435/435/1 1705 | f 415/415/1 416/416/1 437/437/1 436/436/1 1706 | f 416/416/1 417/417/1 438/438/1 437/437/1 1707 | f 417/417/1 418/418/1 439/439/1 438/438/1 1708 | f 418/418/1 419/419/1 440/440/1 439/439/1 1709 | f 419/419/1 420/420/1 441/441/1 440/440/1 1710 | f 421/422/1 422/421/1 443/442/1 442/443/1 1711 | f 422/421/1 423/423/1 444/444/1 443/442/1 1712 | f 423/423/1 424/424/1 445/445/1 444/444/1 1713 | f 424/424/1 425/425/1 446/446/1 445/445/1 1714 | f 425/425/1 426/426/1 447/447/1 446/446/1 1715 | f 426/426/1 427/427/1 448/448/1 447/447/1 1716 | f 427/427/1 428/428/1 449/449/1 448/448/1 1717 | f 428/428/1 429/429/1 450/450/1 449/449/1 1718 | f 429/429/1 430/430/1 451/451/1 450/450/1 1719 | f 430/430/1 431/431/1 452/452/1 451/451/1 1720 | f 431/431/1 432/432/1 453/453/1 452/452/1 1721 | f 432/432/1 433/433/1 454/454/1 453/453/1 1722 | f 433/433/1 434/434/1 455/455/1 454/454/1 1723 | f 434/434/1 435/435/1 456/456/1 455/455/1 1724 | f 435/435/1 436/436/1 457/457/1 456/456/1 1725 | f 436/436/1 437/437/1 458/458/1 457/457/1 1726 | f 437/437/1 438/438/1 459/459/1 458/458/1 1727 | f 438/438/1 439/439/1 460/460/1 459/459/1 1728 | f 439/439/1 440/440/1 461/461/1 460/460/1 1729 | f 440/440/1 441/441/1 462/462/1 461/461/1 1730 | f 442/443/1 443/442/1 464/463/1 463/464/1 1731 | f 443/442/1 444/444/1 465/465/1 464/463/1 1732 | f 444/444/1 445/445/1 466/466/1 465/465/1 1733 | f 445/445/1 446/446/1 467/467/1 466/466/1 1734 | f 446/446/1 447/447/1 468/468/1 467/467/1 1735 | f 447/447/1 448/448/1 469/469/1 468/468/1 1736 | f 448/448/1 449/449/1 470/470/1 469/469/1 1737 | f 449/449/1 450/450/1 471/471/1 470/470/1 1738 | f 450/450/1 451/451/1 472/472/1 471/471/1 1739 | f 451/451/1 452/452/1 473/473/1 472/472/1 1740 | f 452/452/1 453/453/1 474/474/1 473/473/1 1741 | f 453/453/1 454/454/1 475/475/1 474/474/1 1742 | f 454/454/1 455/455/1 476/476/1 475/475/1 1743 | f 455/455/1 456/456/1 477/477/1 476/476/1 1744 | f 456/456/1 457/457/1 478/478/1 477/477/1 1745 | f 457/457/1 458/458/1 479/479/1 478/478/1 1746 | f 458/458/1 459/459/1 480/480/1 479/479/1 1747 | f 459/459/1 460/460/1 481/481/1 480/480/1 1748 | f 460/460/1 461/461/1 482/482/1 481/481/1 1749 | f 461/461/1 462/462/1 483/483/1 482/482/1 1750 | f 463/464/1 464/463/1 485/484/1 484/485/1 1751 | f 464/463/1 465/465/1 486/486/1 485/484/1 1752 | f 465/465/1 466/466/1 487/487/1 486/486/1 1753 | f 466/466/1 467/467/1 488/488/1 487/487/1 1754 | f 467/467/1 468/468/1 489/489/1 488/488/1 1755 | f 468/468/1 469/469/1 490/490/1 489/489/1 1756 | f 469/469/1 470/470/1 491/491/1 490/490/1 1757 | f 470/470/1 471/471/1 492/492/1 491/491/1 1758 | f 471/471/1 472/472/1 493/493/1 492/492/1 1759 | f 472/472/1 473/473/1 494/494/1 493/493/1 1760 | f 473/473/1 474/474/1 495/495/1 494/494/1 1761 | f 474/474/1 475/475/1 496/496/1 495/495/1 1762 | f 475/475/1 476/476/1 497/497/1 496/496/1 1763 | f 476/476/1 477/477/1 498/498/1 497/497/1 1764 | f 477/477/1 478/478/1 499/499/1 498/498/1 1765 | f 478/478/1 479/479/1 500/500/1 499/499/1 1766 | f 479/479/1 480/480/1 501/501/1 500/500/1 1767 | f 480/480/1 481/481/1 502/502/1 501/501/1 1768 | f 481/481/1 482/482/1 503/503/1 502/502/1 1769 | f 482/482/1 483/483/1 504/504/1 503/503/1 1770 | f 484/485/1 485/484/1 506/505/1 505/506/1 1771 | f 485/484/1 486/486/1 507/507/1 506/505/1 1772 | f 486/486/1 487/487/1 508/508/1 507/507/1 1773 | f 487/487/1 488/488/1 509/509/1 508/508/1 1774 | f 488/488/1 489/489/1 510/510/1 509/509/1 1775 | f 489/489/1 490/490/1 511/511/1 510/510/1 1776 | f 490/490/1 491/491/1 512/512/1 511/511/1 1777 | f 491/491/1 492/492/1 513/513/1 512/512/1 1778 | f 492/492/1 493/493/1 514/514/1 513/513/1 1779 | f 493/493/1 494/494/1 515/515/1 514/514/1 1780 | f 494/494/1 495/495/1 516/516/1 515/515/1 1781 | f 495/495/1 496/496/1 517/517/1 516/516/1 1782 | f 496/496/1 497/497/1 518/518/1 517/517/1 1783 | f 497/497/1 498/498/1 519/519/1 518/518/1 1784 | f 498/498/1 499/499/1 520/520/1 519/519/1 1785 | f 499/499/1 500/500/1 521/521/1 520/520/1 1786 | f 500/500/1 501/501/1 522/522/1 521/521/1 1787 | f 501/501/1 502/502/1 523/523/1 522/522/1 1788 | f 502/502/1 503/503/1 524/524/1 523/523/1 1789 | f 503/503/1 504/504/1 525/525/1 524/524/1 1790 | f 505/506/1 506/505/1 527/526/1 526/527/1 1791 | f 506/505/1 507/507/1 528/528/1 527/526/1 1792 | f 507/507/1 508/508/1 529/529/1 528/528/1 1793 | f 508/508/1 509/509/1 530/530/1 529/529/1 1794 | f 509/509/1 510/510/1 531/531/1 530/530/1 1795 | f 510/510/1 511/511/1 532/532/1 531/531/1 1796 | f 511/511/1 512/512/1 533/533/1 532/532/1 1797 | f 512/512/1 513/513/1 534/534/1 533/533/1 1798 | f 513/513/1 514/514/1 535/535/1 534/534/1 1799 | f 514/514/1 515/515/1 536/536/1 535/535/1 1800 | f 515/515/1 516/516/1 537/537/1 536/536/1 1801 | f 516/516/1 517/517/1 538/538/1 537/537/1 1802 | f 517/517/1 518/518/1 539/539/1 538/538/1 1803 | f 518/518/1 519/519/1 540/540/1 539/539/1 1804 | f 519/519/1 520/520/1 541/541/1 540/540/1 1805 | f 520/520/1 521/521/1 542/542/1 541/541/1 1806 | f 521/521/1 522/522/1 543/543/1 542/542/1 1807 | f 522/522/1 523/523/1 544/544/1 543/543/1 1808 | f 523/523/1 524/524/1 545/545/1 544/544/1 1809 | f 524/524/1 525/525/1 546/546/1 545/545/1 1810 | f 526/527/1 527/526/1 548/547/1 547/548/1 1811 | f 527/526/1 528/528/1 549/549/1 548/547/1 1812 | f 528/528/1 529/529/1 550/550/1 549/549/1 1813 | f 529/529/1 530/530/1 551/551/1 550/550/1 1814 | f 530/530/1 531/531/1 552/552/1 551/551/1 1815 | f 531/531/1 532/532/1 553/553/1 552/552/1 1816 | f 532/532/1 533/533/1 554/554/1 553/553/1 1817 | f 533/533/1 534/534/1 555/555/1 554/554/1 1818 | f 534/534/1 535/535/1 556/556/1 555/555/1 1819 | f 535/535/1 536/536/1 557/557/1 556/556/1 1820 | f 536/536/1 537/537/1 558/558/1 557/557/1 1821 | f 537/537/1 538/538/1 559/559/1 558/558/1 1822 | f 538/538/1 539/539/1 560/560/1 559/559/1 1823 | f 539/539/1 540/540/1 561/561/1 560/560/1 1824 | f 540/540/1 541/541/1 562/562/1 561/561/1 1825 | f 541/541/1 542/542/1 563/563/1 562/562/1 1826 | f 542/542/1 543/543/1 564/564/1 563/563/1 1827 | f 543/543/1 544/544/1 565/565/1 564/564/1 1828 | f 544/544/1 545/545/1 566/566/1 565/565/1 1829 | f 545/545/1 546/546/1 567/567/1 566/566/1 1830 | f 547/548/1 548/547/1 569/568/1 568/569/1 1831 | f 548/547/1 549/549/1 570/570/1 569/568/1 1832 | f 549/549/1 550/550/1 571/571/1 570/570/1 1833 | f 550/550/1 551/551/1 572/572/1 571/571/1 1834 | f 551/551/1 552/552/1 573/573/1 572/572/1 1835 | f 552/552/1 553/553/1 574/574/1 573/573/1 1836 | f 553/553/1 554/554/1 575/575/1 574/574/1 1837 | f 554/554/1 555/555/1 576/576/1 575/575/1 1838 | f 555/555/1 556/556/1 577/577/1 576/576/1 1839 | f 556/556/1 557/557/1 578/578/1 577/577/1 1840 | f 557/557/1 558/558/1 579/579/1 578/578/1 1841 | f 558/558/1 559/559/1 580/580/1 579/579/1 1842 | f 559/559/1 560/560/1 581/581/1 580/580/1 1843 | f 560/560/1 561/561/1 582/582/1 581/581/1 1844 | f 561/561/1 562/562/1 583/583/1 582/582/1 1845 | f 562/562/1 563/563/1 584/584/1 583/583/1 1846 | f 563/563/1 564/564/1 585/585/1 584/584/1 1847 | f 564/564/1 565/565/1 586/586/1 585/585/1 1848 | f 565/565/1 566/566/1 587/587/1 586/586/1 1849 | f 566/566/1 567/567/1 588/588/1 587/587/1 1850 | f 568/569/1 569/568/1 590/589/1 589/590/1 1851 | f 569/568/1 570/570/1 591/591/1 590/589/1 1852 | f 570/570/1 571/571/1 592/592/1 591/591/1 1853 | f 571/571/1 572/572/1 593/593/1 592/592/1 1854 | f 572/572/1 573/573/1 594/594/1 593/593/1 1855 | f 573/573/1 574/574/1 595/595/1 594/594/1 1856 | f 574/574/1 575/575/1 596/596/1 595/595/1 1857 | f 575/575/1 576/576/1 597/597/1 596/596/1 1858 | f 576/576/1 577/577/1 598/598/1 597/597/1 1859 | f 577/577/1 578/578/1 599/599/1 598/598/1 1860 | f 578/578/1 579/579/1 600/600/1 599/599/1 1861 | f 579/579/1 580/580/1 601/601/1 600/600/1 1862 | f 580/580/1 581/581/1 602/602/1 601/601/1 1863 | f 581/581/1 582/582/1 603/603/1 602/602/1 1864 | f 582/582/1 583/583/1 604/604/1 603/603/1 1865 | f 583/583/1 584/584/1 605/605/1 604/604/1 1866 | f 584/584/1 585/585/1 606/606/1 605/605/1 1867 | f 585/585/1 586/586/1 607/607/1 606/606/1 1868 | f 586/586/1 587/587/1 608/608/1 607/607/1 1869 | f 587/587/1 588/588/1 609/609/1 608/608/1 1870 | f 589/590/1 590/589/1 611/610/1 610/611/1 1871 | f 590/589/1 591/591/1 612/612/1 611/610/1 1872 | f 591/591/1 592/592/1 613/613/1 612/612/1 1873 | f 592/592/1 593/593/1 614/614/1 613/613/1 1874 | f 593/593/1 594/594/1 615/615/1 614/614/1 1875 | f 594/594/1 595/595/1 616/616/1 615/615/1 1876 | f 595/595/1 596/596/1 617/617/1 616/616/1 1877 | f 596/596/1 597/597/1 618/618/1 617/617/1 1878 | f 597/597/1 598/598/1 619/619/1 618/618/1 1879 | f 598/598/1 599/599/1 620/620/1 619/619/1 1880 | f 599/599/1 600/600/1 621/621/1 620/620/1 1881 | f 600/600/1 601/601/1 622/622/1 621/621/1 1882 | f 601/601/1 602/602/1 623/623/1 622/622/1 1883 | f 602/602/1 603/603/1 624/624/1 623/623/1 1884 | f 603/603/1 604/604/1 625/625/1 624/624/1 1885 | f 604/604/1 605/605/1 626/626/1 625/625/1 1886 | f 605/605/1 606/606/1 627/627/1 626/626/1 1887 | f 606/606/1 607/607/1 628/628/1 627/627/1 1888 | f 607/607/1 608/608/1 629/629/1 628/628/1 1889 | f 608/608/1 609/609/1 630/630/1 629/629/1 1890 | f 610/611/1 611/610/1 632/631/1 631/632/1 1891 | f 611/610/1 612/612/1 633/633/1 632/631/1 1892 | f 612/612/1 613/613/1 634/634/1 633/633/1 1893 | f 613/613/1 614/614/1 635/635/1 634/634/1 1894 | f 614/614/1 615/615/1 636/636/1 635/635/1 1895 | f 615/615/1 616/616/1 637/637/1 636/636/1 1896 | f 616/616/1 617/617/1 638/638/1 637/637/1 1897 | f 617/617/1 618/618/1 639/639/1 638/638/1 1898 | f 618/618/1 619/619/1 640/640/1 639/639/1 1899 | f 619/619/1 620/620/1 641/641/1 640/640/1 1900 | f 620/620/1 621/621/1 642/642/1 641/641/1 1901 | f 621/621/1 622/622/1 643/643/1 642/642/1 1902 | f 622/622/1 623/623/1 644/644/1 643/643/1 1903 | f 623/623/1 624/624/1 645/645/1 644/644/1 1904 | f 624/624/1 625/625/1 646/646/1 645/645/1 1905 | f 625/625/1 626/626/1 647/647/1 646/646/1 1906 | f 626/626/1 627/627/1 648/648/1 647/647/1 1907 | f 627/627/1 628/628/1 649/649/1 648/648/1 1908 | f 628/628/1 629/629/1 650/650/1 649/649/1 1909 | f 629/629/1 630/630/1 651/651/1 650/650/1 1910 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2019" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | 26 | /* Modules */ 27 | "module": "commonjs" /* Specify what module code is generated. */, 28 | // "rootDir": "./", /* Specify the root folder within your source files. */ 29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 33 | "typeRoots": [ 34 | "./node_modules/@webgpu/types", 35 | "./node_modules/@types" 36 | ] /* Specify multiple folders that act like `./node_modules/@types`. */, 37 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 38 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 39 | // "resolveJsonModule": true, /* Enable importing .json files */ 40 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 41 | 42 | /* JavaScript Support */ 43 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 44 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 45 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 46 | 47 | /* Emit */ 48 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 49 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 50 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 51 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 52 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 53 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 54 | // "removeComments": true, /* Disable emitting comments. */ 55 | // "noEmit": true, /* Disable emitting files from a compilation. */ 56 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 57 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 58 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 59 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 60 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 61 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 62 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 63 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 64 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 65 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 66 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 67 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 68 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 69 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 70 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 71 | 72 | /* Interop Constraints */ 73 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 74 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 75 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, 76 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 77 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 78 | 79 | /* Type Checking */ 80 | "strict": true /* Enable all strict type-checking options. */, 81 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 82 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 83 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 84 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 85 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 86 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 87 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 88 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 89 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 90 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 91 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 92 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 93 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 94 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 95 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 96 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 97 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 98 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 99 | 100 | /* Completeness */ 101 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 102 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@^7.0.0": 6 | version "7.16.7" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" 8 | integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== 9 | dependencies: 10 | "@babel/highlight" "^7.16.7" 11 | 12 | "@babel/helper-validator-identifier@^7.16.7": 13 | version "7.16.7" 14 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" 15 | integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== 16 | 17 | "@babel/highlight@^7.16.7": 18 | version "7.17.9" 19 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" 20 | integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== 21 | dependencies: 22 | "@babel/helper-validator-identifier" "^7.16.7" 23 | chalk "^2.0.0" 24 | js-tokens "^4.0.0" 25 | 26 | "@lezer/common@^0.15.0", "@lezer/common@^0.15.7": 27 | version "0.15.12" 28 | resolved "https://registry.yarnpkg.com/@lezer/common/-/common-0.15.12.tgz#2f21aec551dd5fd7d24eb069f90f54d5bc6ee5e9" 29 | integrity sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig== 30 | 31 | "@lezer/lr@^0.15.4": 32 | version "0.15.8" 33 | resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-0.15.8.tgz#1564a911e62b0a0f75ca63794a6aa8c5dc63db21" 34 | integrity sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg== 35 | dependencies: 36 | "@lezer/common" "^0.15.0" 37 | 38 | "@mischnic/json-sourcemap@^0.1.0": 39 | version "0.1.0" 40 | resolved "https://registry.yarnpkg.com/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz#38af657be4108140a548638267d02a2ea3336507" 41 | integrity sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA== 42 | dependencies: 43 | "@lezer/common" "^0.15.7" 44 | "@lezer/lr" "^0.15.4" 45 | json5 "^2.2.1" 46 | 47 | "@parcel/bundler-default@2.5.0": 48 | version "2.5.0" 49 | resolved "https://registry.yarnpkg.com/@parcel/bundler-default/-/bundler-default-2.5.0.tgz#1f0b6d4893bb1a24f49fc7254a423134fb03741e" 50 | integrity sha512-7CJzE17SirCXjcRgBcnqWO/5EOA1raq/3OIKtT4cxbjpDQGHZpjpEEZiMNRpEpdNMxDSlsG8mAkXTYGL2VVWRw== 51 | dependencies: 52 | "@parcel/diagnostic" "2.5.0" 53 | "@parcel/hash" "2.5.0" 54 | "@parcel/plugin" "2.5.0" 55 | "@parcel/utils" "2.5.0" 56 | nullthrows "^1.1.1" 57 | 58 | "@parcel/cache@2.5.0": 59 | version "2.5.0" 60 | resolved "https://registry.yarnpkg.com/@parcel/cache/-/cache-2.5.0.tgz#957620b1b26bfd4f9bd7256ea25ef86e7d6f2816" 61 | integrity sha512-3kOO3cZQv0FAKhrMHGLdb4Qtzpmy78Q6jPN3u8eCY4yqeDTnyQBZvWNHoyCm5WlmL8y6Q6REYMbETLxSH1ggAQ== 62 | dependencies: 63 | "@parcel/fs" "2.5.0" 64 | "@parcel/logger" "2.5.0" 65 | "@parcel/utils" "2.5.0" 66 | lmdb "2.2.4" 67 | 68 | "@parcel/codeframe@2.5.0": 69 | version "2.5.0" 70 | resolved "https://registry.yarnpkg.com/@parcel/codeframe/-/codeframe-2.5.0.tgz#de73dcd69a36e9d0fed1f4361cabfd83df13244a" 71 | integrity sha512-qafqL8Vu2kr932cCWESoDEEoAeKVi7/xdzTBuhzEJng1AfmRT0rCbt/P4ao3RjiDyozPSjXsHOqM6GDZcto4eQ== 72 | dependencies: 73 | chalk "^4.1.0" 74 | 75 | "@parcel/compressor-raw@2.5.0": 76 | version "2.5.0" 77 | resolved "https://registry.yarnpkg.com/@parcel/compressor-raw/-/compressor-raw-2.5.0.tgz#8675d7474b84920e1e4682a5bbd9b417ebfc0bc5" 78 | integrity sha512-I5Zs+2f1ue4sTPdfT8BNsLfTZl48sMWLk2Io3elUJjH/SS9kO7ut5ChkuJtt77ZS35m0OF+ZCt3ICTJdnDG8eA== 79 | dependencies: 80 | "@parcel/plugin" "2.5.0" 81 | 82 | "@parcel/config-default@2.5.0": 83 | version "2.5.0" 84 | resolved "https://registry.yarnpkg.com/@parcel/config-default/-/config-default-2.5.0.tgz#31caa12f6d37f3ae1df68e639dc276039f927603" 85 | integrity sha512-r30V61958SONvP9I8KV8s44ZOFq0H219VyFjPysraSabHjZ+KMaCTQOuqaDtUMa272sHUQkBcZxKYj5jYPJlZg== 86 | dependencies: 87 | "@parcel/bundler-default" "2.5.0" 88 | "@parcel/compressor-raw" "2.5.0" 89 | "@parcel/namer-default" "2.5.0" 90 | "@parcel/optimizer-css" "2.5.0" 91 | "@parcel/optimizer-htmlnano" "2.5.0" 92 | "@parcel/optimizer-image" "2.5.0" 93 | "@parcel/optimizer-svgo" "2.5.0" 94 | "@parcel/optimizer-terser" "2.5.0" 95 | "@parcel/packager-css" "2.5.0" 96 | "@parcel/packager-html" "2.5.0" 97 | "@parcel/packager-js" "2.5.0" 98 | "@parcel/packager-raw" "2.5.0" 99 | "@parcel/packager-svg" "2.5.0" 100 | "@parcel/reporter-dev-server" "2.5.0" 101 | "@parcel/resolver-default" "2.5.0" 102 | "@parcel/runtime-browser-hmr" "2.5.0" 103 | "@parcel/runtime-js" "2.5.0" 104 | "@parcel/runtime-react-refresh" "2.5.0" 105 | "@parcel/runtime-service-worker" "2.5.0" 106 | "@parcel/transformer-babel" "2.5.0" 107 | "@parcel/transformer-css" "2.5.0" 108 | "@parcel/transformer-html" "2.5.0" 109 | "@parcel/transformer-image" "2.5.0" 110 | "@parcel/transformer-js" "2.5.0" 111 | "@parcel/transformer-json" "2.5.0" 112 | "@parcel/transformer-postcss" "2.5.0" 113 | "@parcel/transformer-posthtml" "2.5.0" 114 | "@parcel/transformer-raw" "2.5.0" 115 | "@parcel/transformer-react-refresh-wrap" "2.5.0" 116 | "@parcel/transformer-svg" "2.5.0" 117 | 118 | "@parcel/core@2.5.0": 119 | version "2.5.0" 120 | resolved "https://registry.yarnpkg.com/@parcel/core/-/core-2.5.0.tgz#13f60be9124a6a3e33aff32715acfc5ebade9dd2" 121 | integrity sha512-dygDmPsfAYJKTnUftcbEzjCik7AAaPbFvJW8ETYz8diyjkAG9y6hvCAZIrJE5pNOjFzg32en4v4UWv8Sqlzl9g== 122 | dependencies: 123 | "@mischnic/json-sourcemap" "^0.1.0" 124 | "@parcel/cache" "2.5.0" 125 | "@parcel/diagnostic" "2.5.0" 126 | "@parcel/events" "2.5.0" 127 | "@parcel/fs" "2.5.0" 128 | "@parcel/graph" "2.5.0" 129 | "@parcel/hash" "2.5.0" 130 | "@parcel/logger" "2.5.0" 131 | "@parcel/package-manager" "2.5.0" 132 | "@parcel/plugin" "2.5.0" 133 | "@parcel/source-map" "^2.0.0" 134 | "@parcel/types" "2.5.0" 135 | "@parcel/utils" "2.5.0" 136 | "@parcel/workers" "2.5.0" 137 | abortcontroller-polyfill "^1.1.9" 138 | base-x "^3.0.8" 139 | browserslist "^4.6.6" 140 | clone "^2.1.1" 141 | dotenv "^7.0.0" 142 | dotenv-expand "^5.1.0" 143 | json5 "^2.2.0" 144 | msgpackr "^1.5.4" 145 | nullthrows "^1.1.1" 146 | semver "^5.7.1" 147 | 148 | "@parcel/css-darwin-arm64@1.8.3": 149 | version "1.8.3" 150 | resolved "https://registry.yarnpkg.com/@parcel/css-darwin-arm64/-/css-darwin-arm64-1.8.3.tgz#cd74e2441c89743b22ab61e88e8151222dad591c" 151 | integrity sha512-qh/Ig6GfVjGoiGSWjIYDo6Ghwmyy/9BXvYS1l3R+Bp50F300cq84Czfl6wxaL+aFmghdHzhjJuGfWmZlcYliPA== 152 | 153 | "@parcel/css-darwin-x64@1.8.3": 154 | version "1.8.3" 155 | resolved "https://registry.yarnpkg.com/@parcel/css-darwin-x64/-/css-darwin-x64-1.8.3.tgz#4f11b3e35fc3ef14b608fef324f6b1eff902d671" 156 | integrity sha512-gTUIoRgwyYr4UuH7sSn3gOuMlIshJBOJLmjL+E/mR5lqdYabguiKiRORvkrnb/gHBmOUF9re0RcTaFmJ2VOAlg== 157 | 158 | "@parcel/css-linux-arm-gnueabihf@1.8.3": 159 | version "1.8.3" 160 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm-gnueabihf/-/css-linux-arm-gnueabihf-1.8.3.tgz#f176838487b686da5734d9f52bb56c051dda610e" 161 | integrity sha512-4P1r0BvL9dPz70py2xLg/jEvWJmKNyokPgafyrDP+GbpPTfH5NYJJkVRGo/TkKsp3Rv8SJhV9fdlpFKC6BI92A== 162 | 163 | "@parcel/css-linux-arm64-gnu@1.8.3": 164 | version "1.8.3" 165 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-gnu/-/css-linux-arm64-gnu-1.8.3.tgz#8a9cbacf3bd730400ceb2a6736c5e1741986ba2b" 166 | integrity sha512-1fUy94eaqdzum+C7bsYVF2AgxjLGR/qppArn/4HTQyydHR5QeV+Uoyqo5vdnO5Vclj8eQwlgR9OyAOlmzXxFDA== 167 | 168 | "@parcel/css-linux-arm64-musl@1.8.3": 169 | version "1.8.3" 170 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-musl/-/css-linux-arm64-musl-1.8.3.tgz#35c5f1128469458d71b675b42cbd2f06ddfe5797" 171 | integrity sha512-ct1QRK5gAP8sO22NZ7RULZQB7dbHpou+WMa4z0LJb+Fho13a1JNw931vNHbeI5cRr1fCTDq76pz/+Valgetzcw== 172 | 173 | "@parcel/css-linux-x64-gnu@1.8.3": 174 | version "1.8.3" 175 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-gnu/-/css-linux-x64-gnu-1.8.3.tgz#fa87fd53aa0481e028f6da0ecad94794f58207aa" 176 | integrity sha512-pg/mahoogzjbaZcW76rrTZ64tEu8Wok4Gm0sW/dXHJEJD2QVJ6GxLP4UVNBuhaV0GrNFHggp9pcdhTtLGkKl/g== 177 | 178 | "@parcel/css-linux-x64-musl@1.8.3": 179 | version "1.8.3" 180 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-musl/-/css-linux-x64-musl-1.8.3.tgz#b0df1a3f2edbcf77c056ad03fc78f3cf9449caf1" 181 | integrity sha512-4Iwawy28HQ2yAgbuyR60bgO+8oE+OiWpE02eNjbgqnDpTsfmXFMt4l5OYgZwJJ7DlaZqm+/yO8RPMd+EzwtNzg== 182 | 183 | "@parcel/css-win32-x64-msvc@1.8.3": 184 | version "1.8.3" 185 | resolved "https://registry.yarnpkg.com/@parcel/css-win32-x64-msvc/-/css-win32-x64-msvc-1.8.3.tgz#8719e890a5c0969ca26968b15ffa8e2a20dbe10a" 186 | integrity sha512-vnHUdzIVjqONa5ALFzMJ3ZHt6NiaYTHW/lqzP+AR4l+bq+UTXD2Q75/RgirY5NYwdfy1VPy/jI82jAtLOCymkw== 187 | 188 | "@parcel/css@^1.8.1": 189 | version "1.8.3" 190 | resolved "https://registry.yarnpkg.com/@parcel/css/-/css-1.8.3.tgz#9f06319011a957568e98ede0cf657cb38ea24247" 191 | integrity sha512-6qUN4iicr8f9Q6UUZttwwHMzrb65BRX46PHWq0icA4KEmvmfR9cSYlp/hJH8F4stg3Wncx12Bnw+EuPf5OAEPQ== 192 | dependencies: 193 | detect-libc "^1.0.3" 194 | optionalDependencies: 195 | "@parcel/css-darwin-arm64" "1.8.3" 196 | "@parcel/css-darwin-x64" "1.8.3" 197 | "@parcel/css-linux-arm-gnueabihf" "1.8.3" 198 | "@parcel/css-linux-arm64-gnu" "1.8.3" 199 | "@parcel/css-linux-arm64-musl" "1.8.3" 200 | "@parcel/css-linux-x64-gnu" "1.8.3" 201 | "@parcel/css-linux-x64-musl" "1.8.3" 202 | "@parcel/css-win32-x64-msvc" "1.8.3" 203 | 204 | "@parcel/diagnostic@2.5.0": 205 | version "2.5.0" 206 | resolved "https://registry.yarnpkg.com/@parcel/diagnostic/-/diagnostic-2.5.0.tgz#8c6891924e04b625d50176aae141d24dc8dddf87" 207 | integrity sha512-KiMGGRpEV7wl5gjcxBKcgX84a+cG+IEn94gwy5LK3lENR09nuKShqqgKGAmj/17CobJgw1QNP94/H4Md+oxIWg== 208 | dependencies: 209 | "@mischnic/json-sourcemap" "^0.1.0" 210 | nullthrows "^1.1.1" 211 | 212 | "@parcel/events@2.5.0": 213 | version "2.5.0" 214 | resolved "https://registry.yarnpkg.com/@parcel/events/-/events-2.5.0.tgz#5e108a01a5aa3075038d2a2081fde0432d2559e7" 215 | integrity sha512-Gc2LPwL1H34Ony5MENbKZg7wvCscZ4x9y7Fu92sfbdWpLo3K13hVtsX3TMIIgYt3B7R7OmO8yR880U2T+JfVkQ== 216 | 217 | "@parcel/fs-search@2.5.0": 218 | version "2.5.0" 219 | resolved "https://registry.yarnpkg.com/@parcel/fs-search/-/fs-search-2.5.0.tgz#d96b7c46c2326398e52c9c14cdd07559d598436d" 220 | integrity sha512-uBONkz9ZCNSOqbPGWJY3MNl+pqBTfvzHH9+4UhzHEHPArvK2oD0+syYPVE60+zGrxybXTESYMCJp4bHvH6Z2hA== 221 | dependencies: 222 | detect-libc "^1.0.3" 223 | 224 | "@parcel/fs@2.5.0": 225 | version "2.5.0" 226 | resolved "https://registry.yarnpkg.com/@parcel/fs/-/fs-2.5.0.tgz#2bcb6ccf43826f2bfca9e1ca644be3bf5252c400" 227 | integrity sha512-YYr14BWtx/bJ+hu6PPQQ6G/3omOTWgVqEw+UFI3iQH3P6+e0LRXW/Ja1yAcJeepGcTwIP0opnXZBQOm8PBQ2SA== 228 | dependencies: 229 | "@parcel/fs-search" "2.5.0" 230 | "@parcel/types" "2.5.0" 231 | "@parcel/utils" "2.5.0" 232 | "@parcel/watcher" "^2.0.0" 233 | "@parcel/workers" "2.5.0" 234 | 235 | "@parcel/graph@2.5.0": 236 | version "2.5.0" 237 | resolved "https://registry.yarnpkg.com/@parcel/graph/-/graph-2.5.0.tgz#bd8898d555366a4b261766e22c8652ad869efaff" 238 | integrity sha512-qa2VtG08dJyTaWrxYAkMIlkoDRSPoiqLDNxxHKplkcxAjXBUw0/AkWaz82VO5r1G6jfOj+nM30ajH9uygZYwbw== 239 | dependencies: 240 | "@parcel/utils" "2.5.0" 241 | nullthrows "^1.1.1" 242 | 243 | "@parcel/hash@2.5.0": 244 | version "2.5.0" 245 | resolved "https://registry.yarnpkg.com/@parcel/hash/-/hash-2.5.0.tgz#f2a05f7090f8f27ce8b53afd6272183763101ba7" 246 | integrity sha512-47JL0XpB7UvIW6Ijf8vv+yVMt9dLvB/lRlBHFmAkmovisueVMVbYD7smxVZnCSehD8UH8BcymKbMzyL5dimgoQ== 247 | dependencies: 248 | detect-libc "^1.0.3" 249 | xxhash-wasm "^0.4.2" 250 | 251 | "@parcel/logger@2.5.0": 252 | version "2.5.0" 253 | resolved "https://registry.yarnpkg.com/@parcel/logger/-/logger-2.5.0.tgz#c618b780b80984d821c5bc53f27527fd540f4d0f" 254 | integrity sha512-pT1L3ceH6trL1N3I3r2HawPjz/PCubOo/Kazu7IeXsMsKVjj1a6AeieZHzkNZIbhiGPtm/cHbBNLz2zTWDLeOA== 255 | dependencies: 256 | "@parcel/diagnostic" "2.5.0" 257 | "@parcel/events" "2.5.0" 258 | 259 | "@parcel/markdown-ansi@2.5.0": 260 | version "2.5.0" 261 | resolved "https://registry.yarnpkg.com/@parcel/markdown-ansi/-/markdown-ansi-2.5.0.tgz#e0751d6c8fcd0aa4c8ee0a08d27e9d4d64705410" 262 | integrity sha512-ixkNF3KWIqxMlfxTe9Gb2cp/uNmklQev8VEUxujMVxmUfGyQs4859zdJIQlIinabWYhArhsXATkVf3MzCUN6TQ== 263 | dependencies: 264 | chalk "^4.1.0" 265 | 266 | "@parcel/namer-default@2.5.0": 267 | version "2.5.0" 268 | resolved "https://registry.yarnpkg.com/@parcel/namer-default/-/namer-default-2.5.0.tgz#1e1950a74aca825a753c9aa8e8c37dfb46ef7ef3" 269 | integrity sha512-ahGQqHJzsWE5Qux8zXMAU+lyNBOl+ZpcOFzRGE2DWOsmAlytsHl7DBVCQvzUyNBFg1/HmIj+7D4efv2kjR7rTg== 270 | dependencies: 271 | "@parcel/diagnostic" "2.5.0" 272 | "@parcel/plugin" "2.5.0" 273 | nullthrows "^1.1.1" 274 | 275 | "@parcel/node-resolver-core@2.5.0": 276 | version "2.5.0" 277 | resolved "https://registry.yarnpkg.com/@parcel/node-resolver-core/-/node-resolver-core-2.5.0.tgz#4aaf5c8eb57b56d1257ca02cae5b88be790be6bd" 278 | integrity sha512-XQvpguiIwQcu75cscLDFOVhjsjuPzXbuMaaZ7XxxUEl0PscIgu/GfKYxTfTruN3cRl+CaQH6qBAMfjLaFng6lQ== 279 | dependencies: 280 | "@parcel/diagnostic" "2.5.0" 281 | "@parcel/utils" "2.5.0" 282 | nullthrows "^1.1.1" 283 | 284 | "@parcel/optimizer-css@2.5.0": 285 | version "2.5.0" 286 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-css/-/optimizer-css-2.5.0.tgz#4f64bd0aa29727802b29eaea31aedfbb15ead5e9" 287 | integrity sha512-J00bLF+4SsnKc+YbYrNuBr44/zz3cg++CoXteXhH27PxP1rScGQx36Rui8WORgil5mlX2VYN79DuqJC7V3Ynbg== 288 | dependencies: 289 | "@parcel/css" "^1.8.1" 290 | "@parcel/diagnostic" "2.5.0" 291 | "@parcel/plugin" "2.5.0" 292 | "@parcel/source-map" "^2.0.0" 293 | "@parcel/utils" "2.5.0" 294 | browserslist "^4.6.6" 295 | nullthrows "^1.1.1" 296 | 297 | "@parcel/optimizer-htmlnano@2.5.0": 298 | version "2.5.0" 299 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.5.0.tgz#ffd8b3ef16300f957209cf20e7908a81d6f5b4af" 300 | integrity sha512-Fr0zPqgxoNaOVdROAjNGDWCts3+wByNQ82Mxhu8Tzc25A2cPjcr1H2sa/TE3hf79c92DxdKf2FaC1ZOgR5YPdg== 301 | dependencies: 302 | "@parcel/plugin" "2.5.0" 303 | htmlnano "^2.0.0" 304 | nullthrows "^1.1.1" 305 | posthtml "^0.16.5" 306 | svgo "^2.4.0" 307 | 308 | "@parcel/optimizer-image@2.5.0": 309 | version "2.5.0" 310 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-image/-/optimizer-image-2.5.0.tgz#c80a463bf1dd82782a1f80504c8d660ec7917bc0" 311 | integrity sha512-nbo2pdnAt21WLGjzTpsE8ZEL0xNoP7c3wBj9y70Pysmasg1SrRVCbfE8jTy+lHBQwq2yjC6lV/Usv+9lfA7S/w== 312 | dependencies: 313 | "@parcel/diagnostic" "2.5.0" 314 | "@parcel/plugin" "2.5.0" 315 | "@parcel/utils" "2.5.0" 316 | "@parcel/workers" "2.5.0" 317 | detect-libc "^1.0.3" 318 | 319 | "@parcel/optimizer-svgo@2.5.0": 320 | version "2.5.0" 321 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-svgo/-/optimizer-svgo-2.5.0.tgz#b1c809aa2fbf9229dc3cb62bab399b4576fd8b35" 322 | integrity sha512-pgZqwU0RLc/wr4WcQY/W1GJmddnEANDEpz1mdppUOqBz1EfTQ7zh5NgUA3hV1i05Hbecp3mHSvXJPV0mhNOl5Q== 323 | dependencies: 324 | "@parcel/diagnostic" "2.5.0" 325 | "@parcel/plugin" "2.5.0" 326 | "@parcel/utils" "2.5.0" 327 | svgo "^2.4.0" 328 | 329 | "@parcel/optimizer-terser@2.5.0": 330 | version "2.5.0" 331 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-terser/-/optimizer-terser-2.5.0.tgz#16b3320b34135edac69751ab2f3537a346133086" 332 | integrity sha512-PZ3UHBGfjE49/Jloopsd38Hxg4qzsrdepWP53mCuVP7Aw605Y4QtYuB1ho3VV0oXfKQVq+uI7lVIBsuW4K6vqA== 333 | dependencies: 334 | "@parcel/diagnostic" "2.5.0" 335 | "@parcel/plugin" "2.5.0" 336 | "@parcel/source-map" "^2.0.0" 337 | "@parcel/utils" "2.5.0" 338 | nullthrows "^1.1.1" 339 | terser "^5.2.0" 340 | 341 | "@parcel/package-manager@2.5.0": 342 | version "2.5.0" 343 | resolved "https://registry.yarnpkg.com/@parcel/package-manager/-/package-manager-2.5.0.tgz#9c82236e4e0fa158008b5bc5298def1085913b30" 344 | integrity sha512-zTuF55/lITUjw9dUU/X0HiF++589xbPXw/zUiG9T6s8BQThLvrxAhYP89S719pw7cTqDimGkTxnIuK+a0djEkg== 345 | dependencies: 346 | "@parcel/diagnostic" "2.5.0" 347 | "@parcel/fs" "2.5.0" 348 | "@parcel/logger" "2.5.0" 349 | "@parcel/types" "2.5.0" 350 | "@parcel/utils" "2.5.0" 351 | "@parcel/workers" "2.5.0" 352 | semver "^5.7.1" 353 | 354 | "@parcel/packager-css@2.5.0": 355 | version "2.5.0" 356 | resolved "https://registry.yarnpkg.com/@parcel/packager-css/-/packager-css-2.5.0.tgz#54e36cfee9b32a8be05db7e3a2c37b28f26fa0d1" 357 | integrity sha512-c0mGBFdVSPhAxaX3+zN8KEIqOOUhkIPKbZex1pnGYfy03Qe2/Mb4nyt5DAGlw9gjka1UCHIN/wszLmKC8YyUeg== 358 | dependencies: 359 | "@parcel/plugin" "2.5.0" 360 | "@parcel/source-map" "^2.0.0" 361 | "@parcel/utils" "2.5.0" 362 | nullthrows "^1.1.1" 363 | 364 | "@parcel/packager-html@2.5.0": 365 | version "2.5.0" 366 | resolved "https://registry.yarnpkg.com/@parcel/packager-html/-/packager-html-2.5.0.tgz#c390ca232753d6df73cdae7eff6f96ab6c973600" 367 | integrity sha512-ZFGUPRMWKrm8kQHdkEJ5S22C05qpSymx+o+57EfuNjCrGyj3M59WyGYYXYJ175bFYZ/jp5yy+VxMh6fZefe+Pw== 368 | dependencies: 369 | "@parcel/plugin" "2.5.0" 370 | "@parcel/types" "2.5.0" 371 | "@parcel/utils" "2.5.0" 372 | nullthrows "^1.1.1" 373 | posthtml "^0.16.5" 374 | 375 | "@parcel/packager-js@2.5.0": 376 | version "2.5.0" 377 | resolved "https://registry.yarnpkg.com/@parcel/packager-js/-/packager-js-2.5.0.tgz#3a696207587f57bf5e0c93b2e36db0758f896bea" 378 | integrity sha512-aJAKOTgXdxO3V9O7+2DCVOtne128WwXmUAOVThnMRo7f3zMVSAR7Mxc9pEsuTzPfj8UBXgFBRfdJUSCgsMxiSw== 379 | dependencies: 380 | "@parcel/diagnostic" "2.5.0" 381 | "@parcel/hash" "2.5.0" 382 | "@parcel/plugin" "2.5.0" 383 | "@parcel/source-map" "^2.0.0" 384 | "@parcel/utils" "2.5.0" 385 | globals "^13.2.0" 386 | nullthrows "^1.1.1" 387 | 388 | "@parcel/packager-raw@2.5.0": 389 | version "2.5.0" 390 | resolved "https://registry.yarnpkg.com/@parcel/packager-raw/-/packager-raw-2.5.0.tgz#ce0103c26667c93e5c04eda92691363e93aecb1a" 391 | integrity sha512-aHV0oogeiqxhxS1lsttw15EvG3DDWK3FV7+F+7hoaAy+xg89K56NTp6j43Jtw9iyU1/HnZRGBE2hF3C7N73oKw== 392 | dependencies: 393 | "@parcel/plugin" "2.5.0" 394 | 395 | "@parcel/packager-svg@2.5.0": 396 | version "2.5.0" 397 | resolved "https://registry.yarnpkg.com/@parcel/packager-svg/-/packager-svg-2.5.0.tgz#c6c62cc534ca4107bb724d81dc872ed64faa304d" 398 | integrity sha512-XSMFn30K/kpjcPpQqt88GmPJsNUSVL3RNeigXkIAcLpfO6Tb2eV4iOt4yVCagaDrRJ19alXut0TxjMm5bm41/g== 399 | dependencies: 400 | "@parcel/plugin" "2.5.0" 401 | "@parcel/types" "2.5.0" 402 | "@parcel/utils" "2.5.0" 403 | posthtml "^0.16.4" 404 | 405 | "@parcel/plugin@2.5.0", "@parcel/plugin@^2.0.0-beta.1": 406 | version "2.5.0" 407 | resolved "https://registry.yarnpkg.com/@parcel/plugin/-/plugin-2.5.0.tgz#ae24d9a709581483e0d494a9e09100f0e40956cf" 408 | integrity sha512-obtb6/Gql6YFQ86bdv75A2Noabx8679reFZeyfKKf0L7Lppx4DFQetXwM9XVy7Gx6hJ1Ekm3UMuuIyVJk33YHQ== 409 | dependencies: 410 | "@parcel/types" "2.5.0" 411 | 412 | "@parcel/reporter-cli@2.5.0": 413 | version "2.5.0" 414 | resolved "https://registry.yarnpkg.com/@parcel/reporter-cli/-/reporter-cli-2.5.0.tgz#f64ab15f5faef9c017ea67bf3378343684f267f3" 415 | integrity sha512-miJt2YbRJBmYSVeoUWUj8YL85Pwj1CmGQB0/btqhulGLH/Fvkbv6T4sJ4gl4l5xIt9mJQsZ70pOWwa8BId3rWw== 416 | dependencies: 417 | "@parcel/plugin" "2.5.0" 418 | "@parcel/types" "2.5.0" 419 | "@parcel/utils" "2.5.0" 420 | chalk "^4.1.0" 421 | term-size "^2.2.1" 422 | 423 | "@parcel/reporter-dev-server@2.5.0": 424 | version "2.5.0" 425 | resolved "https://registry.yarnpkg.com/@parcel/reporter-dev-server/-/reporter-dev-server-2.5.0.tgz#043daa2116358d8f806a89d4a7385fe9555a089f" 426 | integrity sha512-wvxAiW42AxJ3B8jtvowJcP4/cTV8zY48SfKg61YKYu1yUO+TtyJIjHQzDW2XuT34cIGFY97Gr0i+AVu44RyUuQ== 427 | dependencies: 428 | "@parcel/plugin" "2.5.0" 429 | "@parcel/utils" "2.5.0" 430 | 431 | "@parcel/resolver-default@2.5.0": 432 | version "2.5.0" 433 | resolved "https://registry.yarnpkg.com/@parcel/resolver-default/-/resolver-default-2.5.0.tgz#b107c59b4f8bbb013091916f349f5fc58e5dfab9" 434 | integrity sha512-39PkZpVr/+iYS11u+lA84vIsKm/yisltTVmUjlYsDnExiuV1c8OSbSdYZ3JMx+7CYPE0bWbosX2AGilIwIMWpQ== 435 | dependencies: 436 | "@parcel/node-resolver-core" "2.5.0" 437 | "@parcel/plugin" "2.5.0" 438 | 439 | "@parcel/runtime-browser-hmr@2.5.0": 440 | version "2.5.0" 441 | resolved "https://registry.yarnpkg.com/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.5.0.tgz#5da8b803cc6bd8a0aac143521ea709f2d13a403f" 442 | integrity sha512-oPAo8Zf06gXCpt41nyvK7kv2HH1RrHAGgOqttyjStwAFlm5MZKs7BgtJzO58LfJN8g3sMY0cNdG17fB/4f8q6Q== 443 | dependencies: 444 | "@parcel/plugin" "2.5.0" 445 | "@parcel/utils" "2.5.0" 446 | 447 | "@parcel/runtime-js@2.5.0": 448 | version "2.5.0" 449 | resolved "https://registry.yarnpkg.com/@parcel/runtime-js/-/runtime-js-2.5.0.tgz#270369beef008f72e2c0814022f573817a12dba1" 450 | integrity sha512-gPC2PbNAiooULP71wF5twe4raekuXsR1Hw/ahITDoqsZdXHzG3CkoCjYL3CkmBGiKQgMMocCyN1E2oBzAH8Kyw== 451 | dependencies: 452 | "@parcel/plugin" "2.5.0" 453 | "@parcel/utils" "2.5.0" 454 | nullthrows "^1.1.1" 455 | 456 | "@parcel/runtime-react-refresh@2.5.0": 457 | version "2.5.0" 458 | resolved "https://registry.yarnpkg.com/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.5.0.tgz#fc74342d77848ea61f364246df70673e83b5430f" 459 | integrity sha512-+8RuDKFdFYIQTrXG4MRhG9XqkkYEHn0zxKyOJ/IkDDfSEhY0na+EyhrneFUwIvDX63gLPkxceXAg0gwBqXPK/Q== 460 | dependencies: 461 | "@parcel/plugin" "2.5.0" 462 | "@parcel/utils" "2.5.0" 463 | react-refresh "^0.9.0" 464 | 465 | "@parcel/runtime-service-worker@2.5.0": 466 | version "2.5.0" 467 | resolved "https://registry.yarnpkg.com/@parcel/runtime-service-worker/-/runtime-service-worker-2.5.0.tgz#609ea02b27cae378f7d9f54820384f7e3494a749" 468 | integrity sha512-STuDlU0fPXeWpAmbayY7o04F0eHy6FTOFeT5KQ0PTxtdEa3Ey8QInP/NVE52Yv0aVQtesWukGrNEFCERlkbFRw== 469 | dependencies: 470 | "@parcel/plugin" "2.5.0" 471 | "@parcel/utils" "2.5.0" 472 | nullthrows "^1.1.1" 473 | 474 | "@parcel/source-map@^2.0.0": 475 | version "2.0.2" 476 | resolved "https://registry.yarnpkg.com/@parcel/source-map/-/source-map-2.0.2.tgz#9aa0b00518cee31d5634de6e9c924a5539b142c1" 477 | integrity sha512-NnUrPYLpYB6qyx2v6bcRPn/gVigmGG6M6xL8wIg/i0dP1GLkuY1nf+Hqdf63FzPTqqT7K3k6eE5yHPQVMO5jcA== 478 | dependencies: 479 | detect-libc "^1.0.3" 480 | 481 | "@parcel/transformer-babel@2.5.0": 482 | version "2.5.0" 483 | resolved "https://registry.yarnpkg.com/@parcel/transformer-babel/-/transformer-babel-2.5.0.tgz#f7f7563a2be9e8bccf7ef48dc61ef8b7be1c0ff0" 484 | integrity sha512-EFb866C9jCoBHIcebWF7goAcYj1wkObx0GDxshlazFtvym1RM27xSWWjRYyqb5+HNOxB3voaNvQOVjcD+DXjCA== 485 | dependencies: 486 | "@parcel/diagnostic" "2.5.0" 487 | "@parcel/plugin" "2.5.0" 488 | "@parcel/source-map" "^2.0.0" 489 | "@parcel/utils" "2.5.0" 490 | browserslist "^4.6.6" 491 | json5 "^2.2.0" 492 | nullthrows "^1.1.1" 493 | semver "^5.7.0" 494 | 495 | "@parcel/transformer-css@2.5.0": 496 | version "2.5.0" 497 | resolved "https://registry.yarnpkg.com/@parcel/transformer-css/-/transformer-css-2.5.0.tgz#8cbe2bd7299a8ef7a965b315da488dcbba1c43d3" 498 | integrity sha512-p8FOvKWWSbS6H8PbD9a0KZqyaKNpSD2BUTzSRYnNj3TBUv7/ZXaP6Om295XTQ/MPht1o7XTQzvfpF/7yEhr02Q== 499 | dependencies: 500 | "@parcel/css" "^1.8.1" 501 | "@parcel/diagnostic" "2.5.0" 502 | "@parcel/plugin" "2.5.0" 503 | "@parcel/source-map" "^2.0.0" 504 | "@parcel/utils" "2.5.0" 505 | browserslist "^4.6.6" 506 | nullthrows "^1.1.1" 507 | 508 | "@parcel/transformer-html@2.5.0": 509 | version "2.5.0" 510 | resolved "https://registry.yarnpkg.com/@parcel/transformer-html/-/transformer-html-2.5.0.tgz#665fecbcb05cf1a4148e752ab99bfaeabfa31051" 511 | integrity sha512-iEjNyAF0wQmY3DMw7FS+UzoOMng76UsSngh+WWA1E5lv5XyqrP8Mk2QLTJp1nWetUhSLhZr58LGmPYBTB4l9ZQ== 512 | dependencies: 513 | "@parcel/diagnostic" "2.5.0" 514 | "@parcel/hash" "2.5.0" 515 | "@parcel/plugin" "2.5.0" 516 | nullthrows "^1.1.1" 517 | posthtml "^0.16.5" 518 | posthtml-parser "^0.10.1" 519 | posthtml-render "^3.0.0" 520 | semver "^5.7.1" 521 | 522 | "@parcel/transformer-image@2.5.0": 523 | version "2.5.0" 524 | resolved "https://registry.yarnpkg.com/@parcel/transformer-image/-/transformer-image-2.5.0.tgz#c0523ea88fb4b6ae18fc7c65b08a5ba6dcd23abd" 525 | integrity sha512-vVEXTHZl8m/9yopgK0dWHLOQX2zOnghq6pZnWdWVG6fsvXZln7kP1YN5iwWDoADQYkiKzP+Ymn6UwP9pZpHFzA== 526 | dependencies: 527 | "@parcel/plugin" "2.5.0" 528 | "@parcel/workers" "2.5.0" 529 | nullthrows "^1.1.1" 530 | 531 | "@parcel/transformer-js@2.5.0": 532 | version "2.5.0" 533 | resolved "https://registry.yarnpkg.com/@parcel/transformer-js/-/transformer-js-2.5.0.tgz#268a6d34898d7c6515c5a64bae535d2c1a7f57a0" 534 | integrity sha512-Cp8Ic+Au3OcskCRZszmo47z3bqcZ7rfPv2xZYXpXY2TzEc3IV0bKje57bZektoY8LW9LkYM9iBO/WhkVoT6LIg== 535 | dependencies: 536 | "@parcel/diagnostic" "2.5.0" 537 | "@parcel/plugin" "2.5.0" 538 | "@parcel/source-map" "^2.0.0" 539 | "@parcel/utils" "2.5.0" 540 | "@parcel/workers" "2.5.0" 541 | "@swc/helpers" "^0.3.6" 542 | browserslist "^4.6.6" 543 | detect-libc "^1.0.3" 544 | nullthrows "^1.1.1" 545 | regenerator-runtime "^0.13.7" 546 | semver "^5.7.1" 547 | 548 | "@parcel/transformer-json@2.5.0": 549 | version "2.5.0" 550 | resolved "https://registry.yarnpkg.com/@parcel/transformer-json/-/transformer-json-2.5.0.tgz#9406b8f0cdd58e65f20fd381a75ece64d346858d" 551 | integrity sha512-661sByA7TkR6Lmxt+hqV4h2SAt+7lgc58DzmUYArpEl1fQnMuQuaB0kQeHzi6fDD2+2G6o7EC+DuwBZKa479TA== 552 | dependencies: 553 | "@parcel/plugin" "2.5.0" 554 | json5 "^2.2.0" 555 | 556 | "@parcel/transformer-postcss@2.5.0": 557 | version "2.5.0" 558 | resolved "https://registry.yarnpkg.com/@parcel/transformer-postcss/-/transformer-postcss-2.5.0.tgz#bff3a36d5a1eb1af4b8c73b9fe5dc50804e449fa" 559 | integrity sha512-IPNlWElekdQHMTBqhdwJNBCQomuYyo7xgNBdnTrt9VJ+R5ihy6n7ZJSWIAJXAH9VZxETTtunfrzRtgkmtjTeZQ== 560 | dependencies: 561 | "@parcel/diagnostic" "2.5.0" 562 | "@parcel/hash" "2.5.0" 563 | "@parcel/plugin" "2.5.0" 564 | "@parcel/utils" "2.5.0" 565 | clone "^2.1.1" 566 | nullthrows "^1.1.1" 567 | postcss-value-parser "^4.2.0" 568 | semver "^5.7.1" 569 | 570 | "@parcel/transformer-posthtml@2.5.0": 571 | version "2.5.0" 572 | resolved "https://registry.yarnpkg.com/@parcel/transformer-posthtml/-/transformer-posthtml-2.5.0.tgz#d4c6558b0443ce94ec5ca823c265ebdf05f3af08" 573 | integrity sha512-AZxg1XD8OXOS4bEGEmBBR+X9T9qoFdVsbVUg498zzejYSka1ZQHF7TgLI/+pUnE+ZVYNIp7/G0xXqsRVKMKmdQ== 574 | dependencies: 575 | "@parcel/plugin" "2.5.0" 576 | "@parcel/utils" "2.5.0" 577 | nullthrows "^1.1.1" 578 | posthtml "^0.16.5" 579 | posthtml-parser "^0.10.1" 580 | posthtml-render "^3.0.0" 581 | semver "^5.7.1" 582 | 583 | "@parcel/transformer-raw@2.5.0": 584 | version "2.5.0" 585 | resolved "https://registry.yarnpkg.com/@parcel/transformer-raw/-/transformer-raw-2.5.0.tgz#5561945e2fd220ac38c0a21aad72175377d048bc" 586 | integrity sha512-I3zjE1u9+Wj90Qqs1V2FTm6iC6SAyOVUthwVZkZey+qbQG/ok682Ez2XjLu7MyQCo9BJNwF/nfOa1hHr3MaJEQ== 587 | dependencies: 588 | "@parcel/plugin" "2.5.0" 589 | 590 | "@parcel/transformer-react-refresh-wrap@2.5.0": 591 | version "2.5.0" 592 | resolved "https://registry.yarnpkg.com/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.5.0.tgz#e1ef71218efb21a78677e8770fb6bcf753caf35c" 593 | integrity sha512-VPqVBxhTN4OQwcjsdyxrv+smjAm4s6dbSWAplgPwdOITMv+a0tjhhJU37WnRC+xxTrbEqRcOt96JvGOkPb8i7g== 594 | dependencies: 595 | "@parcel/plugin" "2.5.0" 596 | "@parcel/utils" "2.5.0" 597 | react-refresh "^0.9.0" 598 | 599 | "@parcel/transformer-svg@2.5.0": 600 | version "2.5.0" 601 | resolved "https://registry.yarnpkg.com/@parcel/transformer-svg/-/transformer-svg-2.5.0.tgz#78fd321e395923f720a886cb5b5c4fae7101c6b3" 602 | integrity sha512-zCGJcrCpICFe0Q/dgjQZfW7sYFkbJEC7NGT4zEJnMo8Cm/kq8Qh6+2ApX6c+vv5Q0WZn5Ic+N0OvxIMkvgdC/w== 603 | dependencies: 604 | "@parcel/diagnostic" "2.5.0" 605 | "@parcel/hash" "2.5.0" 606 | "@parcel/plugin" "2.5.0" 607 | nullthrows "^1.1.1" 608 | posthtml "^0.16.5" 609 | posthtml-parser "^0.10.1" 610 | posthtml-render "^3.0.0" 611 | semver "^5.7.1" 612 | 613 | "@parcel/types@2.5.0": 614 | version "2.5.0" 615 | resolved "https://registry.yarnpkg.com/@parcel/types/-/types-2.5.0.tgz#e3818d4358f849ac2593605b98366b8e156ab533" 616 | integrity sha512-bA0fhG6aXSGYEVo5Dt96x6lseUQHeVZVzgmiRdZsvb614Gvx22ItfaKhPmAVbM9vzbObZDHl9l9G2Ovw8Xve4g== 617 | dependencies: 618 | "@parcel/cache" "2.5.0" 619 | "@parcel/diagnostic" "2.5.0" 620 | "@parcel/fs" "2.5.0" 621 | "@parcel/package-manager" "2.5.0" 622 | "@parcel/source-map" "^2.0.0" 623 | "@parcel/workers" "2.5.0" 624 | utility-types "^3.10.0" 625 | 626 | "@parcel/utils@2.5.0": 627 | version "2.5.0" 628 | resolved "https://registry.yarnpkg.com/@parcel/utils/-/utils-2.5.0.tgz#96d2c7e7226128cc84418ba41770b38aff23ca20" 629 | integrity sha512-kaLGXtQuOOH55KZqXdYDvczhh3mk2eeTVqrrXuuihGjbLKYFlUW2tFDm+5r2s9nCPwTQxOO43ZEOCKSnia+e4w== 630 | dependencies: 631 | "@parcel/codeframe" "2.5.0" 632 | "@parcel/diagnostic" "2.5.0" 633 | "@parcel/hash" "2.5.0" 634 | "@parcel/logger" "2.5.0" 635 | "@parcel/markdown-ansi" "2.5.0" 636 | "@parcel/source-map" "^2.0.0" 637 | chalk "^4.1.0" 638 | 639 | "@parcel/watcher@^2.0.0": 640 | version "2.0.5" 641 | resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.5.tgz#f913a54e1601b0aac972803829b0eece48de215b" 642 | integrity sha512-x0hUbjv891omnkcHD7ZOhiyyUqUUR6MNjq89JhEI3BxppeKWAm6NPQsqqRrAkCJBogdT/o/My21sXtTI9rJIsw== 643 | dependencies: 644 | node-addon-api "^3.2.1" 645 | node-gyp-build "^4.3.0" 646 | 647 | "@parcel/workers@2.5.0": 648 | version "2.5.0" 649 | resolved "https://registry.yarnpkg.com/@parcel/workers/-/workers-2.5.0.tgz#c7f1a4bcd491c7422212724dedbcf7d1e980146e" 650 | integrity sha512-/Ow5OKJWs+9OzV3Jy4J++VnbNx0j3ls/M1CGVBLiBWyCada9DMtquYoBQ4Sk6Uam50BKkIFYetGOeXPNQyyMjg== 651 | dependencies: 652 | "@parcel/diagnostic" "2.5.0" 653 | "@parcel/logger" "2.5.0" 654 | "@parcel/types" "2.5.0" 655 | "@parcel/utils" "2.5.0" 656 | chrome-trace-event "^1.0.2" 657 | nullthrows "^1.1.1" 658 | 659 | "@swc/helpers@^0.3.6": 660 | version "0.3.13" 661 | resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.3.13.tgz#b9af856aaa3804fefdd1544632dde35b7b6ff978" 662 | integrity sha512-A1wswJhnqaLRn8uYVQ8YiNTtY5i/JIPmV08EXXjjTresIkUVUEUaFv/wXVhGXfRNYMvHPkuoMR1Nb6NgpxGjNg== 663 | dependencies: 664 | tslib "^2.4.0" 665 | 666 | "@trysound/sax@0.2.0": 667 | version "0.2.0" 668 | resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" 669 | integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== 670 | 671 | "@types/parse-json@^4.0.0": 672 | version "4.0.0" 673 | resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" 674 | integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== 675 | 676 | "@webgpu/types@^0.1.17": 677 | version "0.1.17" 678 | resolved "https://registry.yarnpkg.com/@webgpu/types/-/types-0.1.17.tgz#91e8ec9fd6a1e63945ef12bff11394949ea1a583" 679 | integrity sha512-M8INbXsMdkWtVsSHRPEiTXHe0S4gxMhYA/Kz4pNoUF9IXd3PHMi6/2n8EAsqkAEdna+aeCm2RmscWV0hsmIf0Q== 680 | 681 | abortcontroller-polyfill@^1.1.9: 682 | version "1.7.3" 683 | resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" 684 | integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q== 685 | 686 | acorn@^8.5.0: 687 | version "8.7.1" 688 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" 689 | integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== 690 | 691 | ansi-styles@^3.2.1: 692 | version "3.2.1" 693 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 694 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 695 | dependencies: 696 | color-convert "^1.9.0" 697 | 698 | ansi-styles@^4.1.0: 699 | version "4.3.0" 700 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 701 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 702 | dependencies: 703 | color-convert "^2.0.1" 704 | 705 | base-x@^3.0.8: 706 | version "3.0.9" 707 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" 708 | integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== 709 | dependencies: 710 | safe-buffer "^5.0.1" 711 | 712 | boolbase@^1.0.0: 713 | version "1.0.0" 714 | resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" 715 | integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= 716 | 717 | browserslist@^4.6.6: 718 | version "4.20.3" 719 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf" 720 | integrity sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg== 721 | dependencies: 722 | caniuse-lite "^1.0.30001332" 723 | electron-to-chromium "^1.4.118" 724 | escalade "^3.1.1" 725 | node-releases "^2.0.3" 726 | picocolors "^1.0.0" 727 | 728 | buffer-from@^1.0.0: 729 | version "1.1.2" 730 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" 731 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 732 | 733 | callsites@^3.0.0: 734 | version "3.1.0" 735 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 736 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 737 | 738 | caniuse-lite@^1.0.30001332: 739 | version "1.0.30001341" 740 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001341.tgz#59590c8ffa8b5939cf4161f00827b8873ad72498" 741 | integrity sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA== 742 | 743 | chalk@^2.0.0: 744 | version "2.4.2" 745 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 746 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 747 | dependencies: 748 | ansi-styles "^3.2.1" 749 | escape-string-regexp "^1.0.5" 750 | supports-color "^5.3.0" 751 | 752 | chalk@^4.1.0: 753 | version "4.1.2" 754 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 755 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 756 | dependencies: 757 | ansi-styles "^4.1.0" 758 | supports-color "^7.1.0" 759 | 760 | chrome-trace-event@^1.0.2: 761 | version "1.0.3" 762 | resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" 763 | integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== 764 | 765 | clone@^2.1.1: 766 | version "2.1.2" 767 | resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" 768 | integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= 769 | 770 | color-convert@^1.9.0: 771 | version "1.9.3" 772 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 773 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 774 | dependencies: 775 | color-name "1.1.3" 776 | 777 | color-convert@^2.0.1: 778 | version "2.0.1" 779 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 780 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 781 | dependencies: 782 | color-name "~1.1.4" 783 | 784 | color-name@1.1.3: 785 | version "1.1.3" 786 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 787 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 788 | 789 | color-name@~1.1.4: 790 | version "1.1.4" 791 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 792 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 793 | 794 | commander@^2.20.0: 795 | version "2.20.3" 796 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 797 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 798 | 799 | commander@^7.0.0, commander@^7.2.0: 800 | version "7.2.0" 801 | resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" 802 | integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== 803 | 804 | cosmiconfig@^7.0.1: 805 | version "7.0.1" 806 | resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" 807 | integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== 808 | dependencies: 809 | "@types/parse-json" "^4.0.0" 810 | import-fresh "^3.2.1" 811 | parse-json "^5.0.0" 812 | path-type "^4.0.0" 813 | yaml "^1.10.0" 814 | 815 | css-select@^4.1.3: 816 | version "4.3.0" 817 | resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" 818 | integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== 819 | dependencies: 820 | boolbase "^1.0.0" 821 | css-what "^6.0.1" 822 | domhandler "^4.3.1" 823 | domutils "^2.8.0" 824 | nth-check "^2.0.1" 825 | 826 | css-tree@^1.1.2, css-tree@^1.1.3: 827 | version "1.1.3" 828 | resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" 829 | integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== 830 | dependencies: 831 | mdn-data "2.0.14" 832 | source-map "^0.6.1" 833 | 834 | css-what@^6.0.1: 835 | version "6.1.0" 836 | resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" 837 | integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== 838 | 839 | csso@^4.2.0: 840 | version "4.2.0" 841 | resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" 842 | integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== 843 | dependencies: 844 | css-tree "^1.1.2" 845 | 846 | detect-libc@^1.0.3: 847 | version "1.0.3" 848 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" 849 | integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= 850 | 851 | dom-serializer@^1.0.1: 852 | version "1.4.1" 853 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" 854 | integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== 855 | dependencies: 856 | domelementtype "^2.0.1" 857 | domhandler "^4.2.0" 858 | entities "^2.0.0" 859 | 860 | domelementtype@^2.0.1, domelementtype@^2.2.0: 861 | version "2.3.0" 862 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" 863 | integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== 864 | 865 | domhandler@^4.2.0, domhandler@^4.2.2, domhandler@^4.3.1: 866 | version "4.3.1" 867 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" 868 | integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== 869 | dependencies: 870 | domelementtype "^2.2.0" 871 | 872 | domutils@^2.8.0: 873 | version "2.8.0" 874 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" 875 | integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== 876 | dependencies: 877 | dom-serializer "^1.0.1" 878 | domelementtype "^2.2.0" 879 | domhandler "^4.2.0" 880 | 881 | dotenv-expand@^5.1.0: 882 | version "5.1.0" 883 | resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" 884 | integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== 885 | 886 | dotenv@^7.0.0: 887 | version "7.0.0" 888 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-7.0.0.tgz#a2be3cd52736673206e8a85fb5210eea29628e7c" 889 | integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g== 890 | 891 | electron-to-chromium@^1.4.118: 892 | version "1.4.137" 893 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz#186180a45617283f1c012284458510cd99d6787f" 894 | integrity sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA== 895 | 896 | entities@^2.0.0: 897 | version "2.2.0" 898 | resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" 899 | integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== 900 | 901 | entities@^3.0.1: 902 | version "3.0.1" 903 | resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" 904 | integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== 905 | 906 | error-ex@^1.3.1: 907 | version "1.3.2" 908 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" 909 | integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== 910 | dependencies: 911 | is-arrayish "^0.2.1" 912 | 913 | escalade@^3.1.1: 914 | version "3.1.1" 915 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 916 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 917 | 918 | escape-string-regexp@^1.0.5: 919 | version "1.0.5" 920 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 921 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 922 | 923 | get-port@^4.2.0: 924 | version "4.2.0" 925 | resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119" 926 | integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw== 927 | 928 | gl-matrix@^3.4.3: 929 | version "3.4.3" 930 | resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9" 931 | integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA== 932 | 933 | globals@^13.2.0: 934 | version "13.15.0" 935 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.15.0.tgz#38113218c907d2f7e98658af246cef8b77e90bac" 936 | integrity sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog== 937 | dependencies: 938 | type-fest "^0.20.2" 939 | 940 | has-flag@^3.0.0: 941 | version "3.0.0" 942 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 943 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 944 | 945 | has-flag@^4.0.0: 946 | version "4.0.0" 947 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 948 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 949 | 950 | htmlnano@^2.0.0: 951 | version "2.0.2" 952 | resolved "https://registry.yarnpkg.com/htmlnano/-/htmlnano-2.0.2.tgz#3e3170941e2446a86211196d740272ebca78f878" 953 | integrity sha512-+ZrQFS4Ub+zd+/fWwfvoYCEGNEa0/zrpys6CyXxvZDwtL7Pl+pOtRkiujyvBQ7Lmfp7/iEPxtOFgxWA16Gkj3w== 954 | dependencies: 955 | cosmiconfig "^7.0.1" 956 | posthtml "^0.16.5" 957 | timsort "^0.3.0" 958 | 959 | htmlparser2@^7.1.1: 960 | version "7.2.0" 961 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-7.2.0.tgz#8817cdea38bbc324392a90b1990908e81a65f5a5" 962 | integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog== 963 | dependencies: 964 | domelementtype "^2.0.1" 965 | domhandler "^4.2.2" 966 | domutils "^2.8.0" 967 | entities "^3.0.1" 968 | 969 | import-fresh@^3.2.1: 970 | version "3.3.0" 971 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 972 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 973 | dependencies: 974 | parent-module "^1.0.0" 975 | resolve-from "^4.0.0" 976 | 977 | is-arrayish@^0.2.1: 978 | version "0.2.1" 979 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 980 | integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= 981 | 982 | is-json@^2.0.1: 983 | version "2.0.1" 984 | resolved "https://registry.yarnpkg.com/is-json/-/is-json-2.0.1.tgz#6be166d144828a131d686891b983df62c39491ff" 985 | integrity sha1-a+Fm0USCihMdaGiRuYPfYsOUkf8= 986 | 987 | js-tokens@^4.0.0: 988 | version "4.0.0" 989 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 990 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 991 | 992 | json-parse-even-better-errors@^2.3.0: 993 | version "2.3.1" 994 | resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" 995 | integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== 996 | 997 | json5@^2.2.0, json5@^2.2.1: 998 | version "2.2.1" 999 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" 1000 | integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== 1001 | 1002 | lines-and-columns@^1.1.6: 1003 | version "1.2.4" 1004 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" 1005 | integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== 1006 | 1007 | lmdb@2.2.4: 1008 | version "2.2.4" 1009 | resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-2.2.4.tgz#6494d5a1d1db152e0be759edcfa06893e4cbdb53" 1010 | integrity sha512-gto+BB2uEob8qRiTlOq+R3uX0YNHsX9mjxj9Sbdue/LIKqu6IlZjrsjKeGyOMquc/474GEqFyX2pdytpydp0rQ== 1011 | dependencies: 1012 | msgpackr "^1.5.4" 1013 | nan "^2.14.2" 1014 | node-gyp-build "^4.2.3" 1015 | ordered-binary "^1.2.4" 1016 | weak-lru-cache "^1.2.2" 1017 | 1018 | lodash.sortby@^4.7.0: 1019 | version "4.7.0" 1020 | resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" 1021 | integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= 1022 | 1023 | mdn-data@2.0.14: 1024 | version "2.0.14" 1025 | resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" 1026 | integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== 1027 | 1028 | msgpackr-extract-darwin-arm64@1.1.0: 1029 | version "1.1.0" 1030 | resolved "https://registry.yarnpkg.com/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-1.1.0.tgz#d590dffac6b90edc3ab53392f7ec5668ed94638c" 1031 | integrity sha512-s1kHoT12tS2cCQOv+Wl3I+/cYNJXBPtwQqGA+dPYoXmchhXiE0Nso+BIfvQ5PxbmAyjj54Q5o7PnLTqVquNfZA== 1032 | 1033 | msgpackr-extract-darwin-x64@1.1.0: 1034 | version "1.1.0" 1035 | resolved "https://registry.yarnpkg.com/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-1.1.0.tgz#568cbdf5e819ac120659c02b0dbaabf483523ee3" 1036 | integrity sha512-yx/H/i12IKg4eWGu/eKdKzJD4jaYvvujQSaVmeOMCesbSQnWo5X6YR9TFjoiNoU9Aexk1KufzL9gW+1DozG1yw== 1037 | 1038 | msgpackr-extract-linux-arm64@1.1.0: 1039 | version "1.1.0" 1040 | resolved "https://registry.yarnpkg.com/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-1.1.0.tgz#c0a30e6687cea4f79115f5762c5fdff90e4a20d4" 1041 | integrity sha512-AxFle3fHNwz2V4CYDIGFxI6o/ZuI0lBKg0uHI8EcCMUmDE5mVAUWYge5WXmORVvb8sVWyVgFlmi3MTu4Ve6tNQ== 1042 | 1043 | msgpackr-extract-linux-arm@1.1.0: 1044 | version "1.1.0" 1045 | resolved "https://registry.yarnpkg.com/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-1.1.0.tgz#38e8db873b6b3986558bde4d7bb15eacc8743a9e" 1046 | integrity sha512-0VvSCqi12xpavxl14gMrauwIzHqHbmSChUijy/uo3mpjB1Pk4vlisKpZsaOZvNJyNKj0ACi5jYtbWnnOd7hYGw== 1047 | 1048 | msgpackr-extract-linux-x64@1.1.0: 1049 | version "1.1.0" 1050 | resolved "https://registry.yarnpkg.com/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-1.1.0.tgz#8c44ca5211d9fa6af77be64a8e687c0be0491ce7" 1051 | integrity sha512-O+XoyNFWpdB8oQL6O/YyzffPpmG5rTNrr1nKLW70HD2ENJUhcITzbV7eZimHPzkn8LAGls1tBaMTHQezTBpFOw== 1052 | 1053 | msgpackr-extract-win32-x64@1.1.0: 1054 | version "1.1.0" 1055 | resolved "https://registry.yarnpkg.com/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-1.1.0.tgz#7bf9bd258e334668842c7532e5e40a60ca3325d7" 1056 | integrity sha512-6AJdM5rNsL4yrskRfhujVSPEd6IBpgvsnIT/TPowKNLQ62iIdryizPY2PJNFiW3AJcY249AHEiDBXS1cTDPxzA== 1057 | 1058 | msgpackr-extract@^1.1.4: 1059 | version "1.1.4" 1060 | resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-1.1.4.tgz#665037c1470f225d01d2d735dad0334fff5faae6" 1061 | integrity sha512-WQbHvsThprXh+EqZYy+SQFEs7z6bNM7a0vgirwUfwUcphWGT2mdPcpyLCNiRsN6w5q5VKJUMblHY+tNEyceb9Q== 1062 | dependencies: 1063 | node-gyp-build-optional-packages "^4.3.2" 1064 | optionalDependencies: 1065 | msgpackr-extract-darwin-arm64 "1.1.0" 1066 | msgpackr-extract-darwin-x64 "1.1.0" 1067 | msgpackr-extract-linux-arm "1.1.0" 1068 | msgpackr-extract-linux-arm64 "1.1.0" 1069 | msgpackr-extract-linux-x64 "1.1.0" 1070 | msgpackr-extract-win32-x64 "1.1.0" 1071 | 1072 | msgpackr@^1.5.4: 1073 | version "1.5.7" 1074 | resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.5.7.tgz#53b3fd0e7afdf4184a594881a18832df9422b660" 1075 | integrity sha512-Hsa80i8W4BiObSMHslfnwC+CC1CYHZzoXJZn0+3EvoCEOgt3c5QlXhdcjgFk2aZxMgpV8aUFZqJyQUCIp4UrzA== 1076 | optionalDependencies: 1077 | msgpackr-extract "^1.1.4" 1078 | 1079 | nan@^2.14.2: 1080 | version "2.15.0" 1081 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" 1082 | integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== 1083 | 1084 | node-addon-api@^3.2.1: 1085 | version "3.2.1" 1086 | resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" 1087 | integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== 1088 | 1089 | node-gyp-build-optional-packages@^4.3.2: 1090 | version "4.3.2" 1091 | resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-4.3.2.tgz#82de9bdf9b1ad042457533afb2f67469dc2264bb" 1092 | integrity sha512-P5Ep3ISdmwcCkZIaBaQamQtWAG0facC89phWZgi5Z3hBU//J6S48OIvyZWSPPf6yQMklLZiqoosWAZUj7N+esA== 1093 | 1094 | node-gyp-build@^4.2.3, node-gyp-build@^4.3.0: 1095 | version "4.4.0" 1096 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" 1097 | integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== 1098 | 1099 | node-releases@^2.0.3: 1100 | version "2.0.4" 1101 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.4.tgz#f38252370c43854dc48aa431c766c6c398f40476" 1102 | integrity sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ== 1103 | 1104 | nth-check@^2.0.1: 1105 | version "2.0.1" 1106 | resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" 1107 | integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== 1108 | dependencies: 1109 | boolbase "^1.0.0" 1110 | 1111 | nullthrows@^1.1.1: 1112 | version "1.1.1" 1113 | resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" 1114 | integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== 1115 | 1116 | ordered-binary@^1.2.4: 1117 | version "1.2.5" 1118 | resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.2.5.tgz#6208c45067eae9d14b8f44791a1d7037adad9147" 1119 | integrity sha512-djRmZoEpOGvIRW7ufsCDHtvcUa18UC9TxnPbHhSVFZHsoyg0dtut1bWtBZ/fmxdPN62oWXrV6adM7NoWU+CneA== 1120 | 1121 | parcel-reporter-static-files-copy@^1.3.4: 1122 | version "1.3.4" 1123 | resolved "https://registry.yarnpkg.com/parcel-reporter-static-files-copy/-/parcel-reporter-static-files-copy-1.3.4.tgz#73694a4eb0da96c91c9cdcf9b3658f959b6c5d74" 1124 | integrity sha512-JRTzz8P7jyaHdj1piBY+YzkWrNFmi+LKYdImxAdoOimdYCpeM1Tuk4vVEhVxeh2lN83MBxc72evWm0lPaZGWZA== 1125 | dependencies: 1126 | "@parcel/plugin" "^2.0.0-beta.1" 1127 | 1128 | parcel@^2.5.0: 1129 | version "2.5.0" 1130 | resolved "https://registry.yarnpkg.com/parcel/-/parcel-2.5.0.tgz#b6f01c665b6085e4eb58957ff11bc8f4027bd8f7" 1131 | integrity sha512-er0mj/BaMjWyzQ/jedLUi/LNAuQcFT8lCvoNqANF+jTaX9rohaBwxIvKVJVAZgyCnmyfbbldp496wPMW0R0+CA== 1132 | dependencies: 1133 | "@parcel/config-default" "2.5.0" 1134 | "@parcel/core" "2.5.0" 1135 | "@parcel/diagnostic" "2.5.0" 1136 | "@parcel/events" "2.5.0" 1137 | "@parcel/fs" "2.5.0" 1138 | "@parcel/logger" "2.5.0" 1139 | "@parcel/package-manager" "2.5.0" 1140 | "@parcel/reporter-cli" "2.5.0" 1141 | "@parcel/reporter-dev-server" "2.5.0" 1142 | "@parcel/utils" "2.5.0" 1143 | chalk "^4.1.0" 1144 | commander "^7.0.0" 1145 | get-port "^4.2.0" 1146 | v8-compile-cache "^2.0.0" 1147 | 1148 | parent-module@^1.0.0: 1149 | version "1.0.1" 1150 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 1151 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 1152 | dependencies: 1153 | callsites "^3.0.0" 1154 | 1155 | parse-json@^5.0.0: 1156 | version "5.2.0" 1157 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" 1158 | integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== 1159 | dependencies: 1160 | "@babel/code-frame" "^7.0.0" 1161 | error-ex "^1.3.1" 1162 | json-parse-even-better-errors "^2.3.0" 1163 | lines-and-columns "^1.1.6" 1164 | 1165 | path-type@^4.0.0: 1166 | version "4.0.0" 1167 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" 1168 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 1169 | 1170 | picocolors@^1.0.0: 1171 | version "1.0.0" 1172 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" 1173 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 1174 | 1175 | postcss-value-parser@^4.2.0: 1176 | version "4.2.0" 1177 | resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" 1178 | integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== 1179 | 1180 | posthtml-parser@^0.10.1: 1181 | version "0.10.2" 1182 | resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.10.2.tgz#df364d7b179f2a6bf0466b56be7b98fd4e97c573" 1183 | integrity sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg== 1184 | dependencies: 1185 | htmlparser2 "^7.1.1" 1186 | 1187 | posthtml-parser@^0.11.0: 1188 | version "0.11.0" 1189 | resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.11.0.tgz#25d1c7bf811ea83559bc4c21c189a29747a24b7a" 1190 | integrity sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw== 1191 | dependencies: 1192 | htmlparser2 "^7.1.1" 1193 | 1194 | posthtml-render@^3.0.0: 1195 | version "3.0.0" 1196 | resolved "https://registry.yarnpkg.com/posthtml-render/-/posthtml-render-3.0.0.tgz#97be44931496f495b4f07b99e903cc70ad6a3205" 1197 | integrity sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA== 1198 | dependencies: 1199 | is-json "^2.0.1" 1200 | 1201 | posthtml@^0.16.4, posthtml@^0.16.5: 1202 | version "0.16.6" 1203 | resolved "https://registry.yarnpkg.com/posthtml/-/posthtml-0.16.6.tgz#e2fc407f67a64d2fa3567afe770409ffdadafe59" 1204 | integrity sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ== 1205 | dependencies: 1206 | posthtml-parser "^0.11.0" 1207 | posthtml-render "^3.0.0" 1208 | 1209 | punycode@^2.1.0: 1210 | version "2.1.1" 1211 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 1212 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 1213 | 1214 | react-refresh@^0.9.0: 1215 | version "0.9.0" 1216 | resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf" 1217 | integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ== 1218 | 1219 | regenerator-runtime@^0.13.7: 1220 | version "0.13.9" 1221 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" 1222 | integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== 1223 | 1224 | resolve-from@^4.0.0: 1225 | version "4.0.0" 1226 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 1227 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 1228 | 1229 | safe-buffer@^5.0.1: 1230 | version "5.2.1" 1231 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1232 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1233 | 1234 | semver@^5.7.0, semver@^5.7.1: 1235 | version "5.7.1" 1236 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 1237 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 1238 | 1239 | source-map-support@~0.5.20: 1240 | version "0.5.21" 1241 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" 1242 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== 1243 | dependencies: 1244 | buffer-from "^1.0.0" 1245 | source-map "^0.6.0" 1246 | 1247 | source-map@^0.6.0, source-map@^0.6.1: 1248 | version "0.6.1" 1249 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1250 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1251 | 1252 | source-map@~0.8.0-beta.0: 1253 | version "0.8.0-beta.0" 1254 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" 1255 | integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== 1256 | dependencies: 1257 | whatwg-url "^7.0.0" 1258 | 1259 | stable@^0.1.8: 1260 | version "0.1.8" 1261 | resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" 1262 | integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== 1263 | 1264 | supports-color@^5.3.0: 1265 | version "5.5.0" 1266 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1267 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1268 | dependencies: 1269 | has-flag "^3.0.0" 1270 | 1271 | supports-color@^7.1.0: 1272 | version "7.2.0" 1273 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1274 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1275 | dependencies: 1276 | has-flag "^4.0.0" 1277 | 1278 | svgo@^2.4.0: 1279 | version "2.8.0" 1280 | resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" 1281 | integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== 1282 | dependencies: 1283 | "@trysound/sax" "0.2.0" 1284 | commander "^7.2.0" 1285 | css-select "^4.1.3" 1286 | css-tree "^1.1.3" 1287 | csso "^4.2.0" 1288 | picocolors "^1.0.0" 1289 | stable "^0.1.8" 1290 | 1291 | term-size@^2.2.1: 1292 | version "2.2.1" 1293 | resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" 1294 | integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== 1295 | 1296 | terser@^5.2.0: 1297 | version "5.13.1" 1298 | resolved "https://registry.yarnpkg.com/terser/-/terser-5.13.1.tgz#66332cdc5a01b04a224c9fad449fc1a18eaa1799" 1299 | integrity sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA== 1300 | dependencies: 1301 | acorn "^8.5.0" 1302 | commander "^2.20.0" 1303 | source-map "~0.8.0-beta.0" 1304 | source-map-support "~0.5.20" 1305 | 1306 | timsort@^0.3.0: 1307 | version "0.3.0" 1308 | resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" 1309 | integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= 1310 | 1311 | tr46@^1.0.1: 1312 | version "1.0.1" 1313 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" 1314 | integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= 1315 | dependencies: 1316 | punycode "^2.1.0" 1317 | 1318 | tslib@^2.4.0: 1319 | version "2.4.0" 1320 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" 1321 | integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== 1322 | 1323 | type-fest@^0.20.2: 1324 | version "0.20.2" 1325 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" 1326 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 1327 | 1328 | typescript@^4.6.4: 1329 | version "4.6.4" 1330 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" 1331 | integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== 1332 | 1333 | utility-types@^3.10.0: 1334 | version "3.10.0" 1335 | resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" 1336 | integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== 1337 | 1338 | v8-compile-cache@^2.0.0: 1339 | version "2.3.0" 1340 | resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" 1341 | integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== 1342 | 1343 | weak-lru-cache@^1.2.2: 1344 | version "1.2.2" 1345 | resolved "https://registry.yarnpkg.com/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz#fdbb6741f36bae9540d12f480ce8254060dccd19" 1346 | integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw== 1347 | 1348 | webidl-conversions@^4.0.2: 1349 | version "4.0.2" 1350 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" 1351 | integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== 1352 | 1353 | whatwg-url@^7.0.0: 1354 | version "7.1.0" 1355 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" 1356 | integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== 1357 | dependencies: 1358 | lodash.sortby "^4.7.0" 1359 | tr46 "^1.0.1" 1360 | webidl-conversions "^4.0.2" 1361 | 1362 | xxhash-wasm@^0.4.2: 1363 | version "0.4.2" 1364 | resolved "https://registry.yarnpkg.com/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz#752398c131a4dd407b5132ba62ad372029be6f79" 1365 | integrity sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA== 1366 | 1367 | yaml@^1.10.0: 1368 | version "1.10.2" 1369 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" 1370 | integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== 1371 | --------------------------------------------------------------------------------