angular-three-cannon 2.0.0-beta.7 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -4
- package/body/README.md +49 -0
- package/body/index.d.ts +2 -0
- package/body/lib/body.d.ts +17 -0
- package/body/lib/types.d.ts +49 -0
- package/body/lib/utils.d.ts +50 -0
- package/constraint/README.md +47 -0
- package/constraint/index.d.ts +1 -0
- package/constraint/lib/constraint.d.ts +32 -0
- package/debug/README.md +48 -2
- package/debug/index.d.ts +1 -1
- package/debug/lib/debug.d.ts +25 -0
- package/esm2022/body/angular-three-cannon-body.mjs +5 -0
- package/esm2022/body/index.mjs +2 -0
- package/esm2022/body/lib/body.mjs +108 -0
- package/esm2022/body/lib/types.mjs +2 -0
- package/esm2022/body/lib/utils.mjs +193 -0
- package/esm2022/constraint/angular-three-cannon-constraint.mjs +5 -0
- package/esm2022/constraint/index.mjs +2 -0
- package/esm2022/constraint/lib/constraint.mjs +67 -0
- package/esm2022/debug/index.mjs +2 -2
- package/esm2022/debug/lib/debug.mjs +82 -0
- package/esm2022/index.mjs +2 -2
- package/esm2022/lib/physics.mjs +192 -0
- package/fesm2022/angular-three-cannon-body.mjs +306 -0
- package/fesm2022/angular-three-cannon-body.mjs.map +1 -0
- package/fesm2022/angular-three-cannon-constraint.mjs +74 -0
- package/fesm2022/angular-three-cannon-constraint.mjs.map +1 -0
- package/fesm2022/angular-three-cannon-debug.mjs +61 -77
- package/fesm2022/angular-three-cannon-debug.mjs.map +1 -1
- package/fesm2022/angular-three-cannon.mjs +139 -240
- package/fesm2022/angular-three-cannon.mjs.map +1 -1
- package/index.d.ts +1 -1
- package/lib/physics.d.ts +61 -0
- package/package.json +25 -19
- package/debug/debug.d.ts +0 -26
- package/esm2022/debug/debug.mjs +0 -99
- package/esm2022/physics.mjs +0 -294
- package/esm2022/services/angular-three-cannon-services.mjs +0 -5
- package/esm2022/services/body.mjs +0 -294
- package/esm2022/services/constraint.mjs +0 -59
- package/esm2022/services/contact-material.mjs +0 -20
- package/esm2022/services/index.mjs +0 -7
- package/esm2022/services/ray.mjs +0 -30
- package/esm2022/services/raycast-vehicle.mjs +0 -72
- package/esm2022/services/spring.mjs +0 -34
- package/fesm2022/angular-three-cannon-services.mjs +0 -499
- package/fesm2022/angular-three-cannon-services.mjs.map +0 -1
- package/physics.d.ts +0 -97
- package/plugin/README.md +0 -11
- package/plugin/generators.json +0 -19
- package/plugin/package.json +0 -9
- package/plugin/src/generators/init/compat.d.ts +0 -2
- package/plugin/src/generators/init/compat.js +0 -6
- package/plugin/src/generators/init/compat.js.map +0 -1
- package/plugin/src/generators/init/init.d.ts +0 -5
- package/plugin/src/generators/init/init.js +0 -24
- package/plugin/src/generators/init/init.js.map +0 -1
- package/plugin/src/generators/init/schema.json +0 -7
- package/plugin/src/index.d.ts +0 -1
- package/plugin/src/index.js +0 -6
- package/plugin/src/index.js.map +0 -1
- package/services/README.md +0 -3
- package/services/body.d.ts +0 -60
- package/services/constraint.d.ts +0 -31
- package/services/contact-material.d.ts +0 -9
- package/services/index.d.ts +0 -6
- package/services/ray.d.ts +0 -12
- package/services/raycast-vehicle.d.ts +0 -30
- package/services/spring.d.ts +0 -19
package/README.md
CHANGED
|
@@ -1,7 +1,74 @@
|
|
|
1
|
-
# cannon
|
|
1
|
+
# `angular-three-cannon`
|
|
2
2
|
|
|
3
|
-
This library
|
|
3
|
+
This library is a wrapper around the [Cannon.js](https://schteppe.github.io/cannon.js/) physics engine for use with Angular Three.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install angular-three-cannon cannon-es @pmndrs/cannon-worker-api
|
|
9
|
+
# yarn add angular-three-cannon cannon-es @pmndrs/cannon-worker-api
|
|
10
|
+
# pnpm add angular-three-cannon cannon-es @pmndrs/cannon-worker-api
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> Make sure to already have `angular-three` installed
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
@Component({
|
|
19
|
+
template: `
|
|
20
|
+
<ngt-mesh #mesh>
|
|
21
|
+
<ngt-box-geometry />
|
|
22
|
+
</ngt-mesh>
|
|
23
|
+
`,
|
|
24
|
+
})
|
|
25
|
+
export class Box {
|
|
26
|
+
mesh = viewChild.required<ElementRef<Mesh>>('mesh');
|
|
27
|
+
|
|
28
|
+
constructor() {
|
|
29
|
+
// Make this mesh a Box body in Physics. Only works within ngtc-physics
|
|
30
|
+
injectBox(() => ({ mass: 10000, position: [0, 0, 0], args: [1, 1, 1] }), this.mesh);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@Component({
|
|
35
|
+
template: `
|
|
36
|
+
<ngtc-physics>
|
|
37
|
+
<app-box />
|
|
38
|
+
</ngtc-physics>
|
|
39
|
+
`,
|
|
40
|
+
imports: [NgtcPhysics, Box],
|
|
41
|
+
})
|
|
42
|
+
export class SceneGraph {}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Inputs
|
|
46
|
+
|
|
47
|
+
- `allowSleep?: boolean`
|
|
48
|
+
- `axisIndex?: 0 | 1 | 2`
|
|
49
|
+
- `broadphase?: 'Naive' | 'SAP'`
|
|
50
|
+
- `defaultContactMaterial?: ContactMaterialOptions`
|
|
51
|
+
- `frictionGravity?: Vector3 | null`
|
|
52
|
+
- `gravity?: Vector3`
|
|
53
|
+
- `isPaused?: boolean`
|
|
54
|
+
- `iterations?: number`
|
|
55
|
+
- `maxSubSteps?: number`
|
|
56
|
+
- `quatNormalizeFast?: boolean`
|
|
57
|
+
- `quatNormalizeSkip?: number`
|
|
58
|
+
- `shouldInvalidate?: boolean`
|
|
59
|
+
- `size?: number`
|
|
60
|
+
- `solver?: 'GS' | 'Split'`
|
|
61
|
+
- `stepSize?: number`
|
|
62
|
+
- `tolerance?: number`
|
|
63
|
+
|
|
64
|
+
## Debug
|
|
65
|
+
|
|
66
|
+
Read the [debug documentation](./debug/README.md) for more information on how to enable debug mode and view debug information.
|
|
67
|
+
|
|
68
|
+
## Bodies
|
|
69
|
+
|
|
70
|
+
Read the [body documentation](./body/README.md) for more information on how to create physics bodies and apply forces.
|
|
71
|
+
|
|
72
|
+
## Constraints
|
|
73
|
+
|
|
74
|
+
Read the [constraint documentation](./constraint/README.md) for more information on how to create constraints between physics bodies.
|
package/body/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# `angular-three-cannon/body`
|
|
2
|
+
|
|
3
|
+
This module provides a set of custom injector functions to create physics bodies that link `ngt-*` objects in THREE.js with bodies in the Cannon.js physics world. These functions simplify the process of adding physics behavior to your 3D objects.
|
|
4
|
+
|
|
5
|
+
### Available `inject*` Functions
|
|
6
|
+
|
|
7
|
+
| Function | Description | `getProps` Arguments | `object` Type |
|
|
8
|
+
| :----------------------- | :----------------------------------------------- | :----------------------------------------------------------------------- | :------------ |
|
|
9
|
+
| `injectBox` | Creates a box-shaped physics body. | `mass`, `position`, `args: [width, height, depth]` | `ElementRef` |
|
|
10
|
+
| `injectConvexPolyhedron` | Creates a convex polyhedron-shaped physics body. | `mass`, `position`, `vertices`, `faces` | `ElementRef` |
|
|
11
|
+
| `injectCylinder` | Creates a cylinder-shaped physics body. | `mass`, `position`, `radiusTop`, `radiusBottom`, `height`, `numSegments` | `ElementRef` |
|
|
12
|
+
| `injectHeightfield` | Creates a heightfield-shaped physics body. | `mass`, `position`, `data`, `elementSize` | `ElementRef` |
|
|
13
|
+
| `injectParticle` | Creates a particle physics body. | `mass`, `position` | `ElementRef` |
|
|
14
|
+
| `injectPlane` | Creates a plane-shaped physics body. | `mass`, `position` | `ElementRef` |
|
|
15
|
+
| `injectSphere` | Creates a sphere-shaped physics body. | `mass`, `position`, `radius` | `ElementRef` |
|
|
16
|
+
| `injectTrimesh` | Creates a trimesh-shaped physics body. | `mass`, `position`, `vertices`, `indices` | `ElementRef` |
|
|
17
|
+
| `injectCompound` | Creates a compound physics body. | `mass`, `position`, `shapes` | `ElementRef` |
|
|
18
|
+
|
|
19
|
+
**All functions also accept an optional `options` argument for additional customization.**
|
|
20
|
+
|
|
21
|
+
### Simple Usage of `injectBox()`
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
@Component({
|
|
25
|
+
template: `
|
|
26
|
+
<ngt-mesh #mesh>
|
|
27
|
+
<ngt-box-geometry />
|
|
28
|
+
</ngt-mesh>
|
|
29
|
+
`,
|
|
30
|
+
})
|
|
31
|
+
export class Box {
|
|
32
|
+
mesh = viewChild.required<ElementRef<Mesh>>('mesh');
|
|
33
|
+
|
|
34
|
+
constructor() {
|
|
35
|
+
// Make this mesh a Box body in Physics. Only works within ngtc-physics
|
|
36
|
+
injectBox(() => ({ mass: 10000, position: [0, 0, 0], args: [1, 1, 1] }), this.mesh);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Component({
|
|
41
|
+
template: `
|
|
42
|
+
<ngtc-physics>
|
|
43
|
+
<app-box />
|
|
44
|
+
</ngtc-physics>
|
|
45
|
+
`,
|
|
46
|
+
imports: [NgtcPhysics, Box],
|
|
47
|
+
})
|
|
48
|
+
export class SceneGraph {}
|
|
49
|
+
```
|
package/body/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ElementRef, Injector, Signal } from '@angular/core';
|
|
2
|
+
import { BodyShapeType } from '@pmndrs/cannon-worker-api';
|
|
3
|
+
import { Object3D } from 'three';
|
|
4
|
+
import { NgtcArgFn, NgtcBodyPropsMap, NgtcBodyPublicApi, NgtcGetByIndex } from './types';
|
|
5
|
+
export interface NgtcBodyOptions<TShape extends BodyShapeType> {
|
|
6
|
+
transformArgs?: NgtcArgFn<NgtcBodyPropsMap[TShape]>;
|
|
7
|
+
injector?: Injector;
|
|
8
|
+
}
|
|
9
|
+
export declare const injectBox: <TObject extends Object3D>(getPropFn: NgtcGetByIndex<import("@pmndrs/cannon-worker-api").BoxProps>, ref: TObject | ElementRef<TObject> | Signal<TObject | ElementRef<TObject> | undefined>, options?: NgtcBodyOptions<"Box"> | undefined) => Signal<NgtcBodyPublicApi | null>;
|
|
10
|
+
export declare const injectConvexPolyhedron: <TObject extends Object3D>(getPropFn: NgtcGetByIndex<import("@pmndrs/cannon-worker-api").ConvexPolyhedronProps>, ref: TObject | ElementRef<TObject> | Signal<TObject | ElementRef<TObject> | undefined>, options?: NgtcBodyOptions<"ConvexPolyhedron"> | undefined) => Signal<NgtcBodyPublicApi | null>;
|
|
11
|
+
export declare const injectCylinder: <TObject extends Object3D>(getPropFn: NgtcGetByIndex<import("@pmndrs/cannon-worker-api").CylinderProps>, ref: TObject | ElementRef<TObject> | Signal<TObject | ElementRef<TObject> | undefined>, options?: NgtcBodyOptions<"Cylinder"> | undefined) => Signal<NgtcBodyPublicApi | null>;
|
|
12
|
+
export declare const injectHeightfield: <TObject extends Object3D>(getPropFn: NgtcGetByIndex<import("@pmndrs/cannon-worker-api").HeightfieldProps>, ref: TObject | ElementRef<TObject> | Signal<TObject | ElementRef<TObject> | undefined>, options?: NgtcBodyOptions<"Heightfield"> | undefined) => Signal<NgtcBodyPublicApi | null>;
|
|
13
|
+
export declare const injectParticle: <TObject extends Object3D>(getPropFn: NgtcGetByIndex<import("@pmndrs/cannon-worker-api").ParticleProps>, ref: TObject | ElementRef<TObject> | Signal<TObject | ElementRef<TObject> | undefined>, options?: NgtcBodyOptions<"Particle"> | undefined) => Signal<NgtcBodyPublicApi | null>;
|
|
14
|
+
export declare const injectPlane: <TObject extends Object3D>(getPropFn: NgtcGetByIndex<import("@pmndrs/cannon-worker-api").PlaneProps>, ref: TObject | ElementRef<TObject> | Signal<TObject | ElementRef<TObject> | undefined>, options?: NgtcBodyOptions<"Plane"> | undefined) => Signal<NgtcBodyPublicApi | null>;
|
|
15
|
+
export declare const injectSphere: <TObject extends Object3D>(getPropFn: NgtcGetByIndex<import("@pmndrs/cannon-worker-api").SphereProps>, ref: TObject | ElementRef<TObject> | Signal<TObject | ElementRef<TObject> | undefined>, options?: NgtcBodyOptions<"Sphere"> | undefined) => Signal<NgtcBodyPublicApi | null>;
|
|
16
|
+
export declare const injectTrimesh: <TObject extends Object3D>(getPropFn: NgtcGetByIndex<import("@pmndrs/cannon-worker-api").TrimeshProps>, ref: TObject | ElementRef<TObject> | Signal<TObject | ElementRef<TObject> | undefined>, options?: NgtcBodyOptions<"Trimesh"> | undefined) => Signal<NgtcBodyPublicApi | null>;
|
|
17
|
+
export declare const injectCompound: <TObject extends Object3D>(getPropFn: NgtcGetByIndex<import("@pmndrs/cannon-worker-api").CompoundBodyProps>, ref: TObject | ElementRef<TObject> | Signal<TObject | ElementRef<TObject> | undefined>, options?: NgtcBodyOptions<"Compound"> | undefined) => Signal<NgtcBodyPublicApi | null>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { AtomicName, AtomicProps, BodyProps, BoxProps, CompoundBodyProps, ConvexPolyhedronProps, CylinderProps, HeightfieldProps, ParticleProps, PlaneProps, Quad, SphereProps, TrimeshProps, Triplet, VectorName } from '@pmndrs/cannon-worker-api';
|
|
2
|
+
import { Euler, Quaternion, Vector3 } from 'three';
|
|
3
|
+
export interface NgtcAtomicApi<K extends AtomicName> {
|
|
4
|
+
set: (value: AtomicProps[K]) => void;
|
|
5
|
+
subscribe: (callback: (value: AtomicProps[K]) => void) => () => void;
|
|
6
|
+
}
|
|
7
|
+
export interface NgtcQuaternionApi {
|
|
8
|
+
copy: ({ w, x, y, z }: Quaternion) => void;
|
|
9
|
+
set: (x: number, y: number, z: number, w: number) => void;
|
|
10
|
+
subscribe: (callback: (value: Quad) => void) => () => void;
|
|
11
|
+
}
|
|
12
|
+
export interface NgtcVectorApi {
|
|
13
|
+
copy: ({ x, y, z }: Vector3 | Euler) => void;
|
|
14
|
+
set: (x: number, y: number, z: number) => void;
|
|
15
|
+
subscribe: (callback: (value: Triplet) => void) => () => void;
|
|
16
|
+
}
|
|
17
|
+
export type NgtcWorkerApi = {
|
|
18
|
+
[K in AtomicName]: NgtcAtomicApi<K>;
|
|
19
|
+
} & {
|
|
20
|
+
[K in VectorName]: NgtcVectorApi;
|
|
21
|
+
} & {
|
|
22
|
+
applyForce: (force: Triplet, worldPoint: Triplet) => void;
|
|
23
|
+
applyImpulse: (impulse: Triplet, worldPoint: Triplet) => void;
|
|
24
|
+
applyLocalForce: (force: Triplet, localPoint: Triplet) => void;
|
|
25
|
+
applyLocalImpulse: (impulse: Triplet, localPoint: Triplet) => void;
|
|
26
|
+
applyTorque: (torque: Triplet) => void;
|
|
27
|
+
quaternion: NgtcQuaternionApi;
|
|
28
|
+
rotation: NgtcVectorApi;
|
|
29
|
+
scaleOverride: (scale: Triplet) => void;
|
|
30
|
+
sleep: () => void;
|
|
31
|
+
wakeUp: () => void;
|
|
32
|
+
remove: () => void;
|
|
33
|
+
};
|
|
34
|
+
export interface NgtcBodyPublicApi extends NgtcWorkerApi {
|
|
35
|
+
at: (index: number) => NgtcWorkerApi;
|
|
36
|
+
}
|
|
37
|
+
export interface NgtcBodyPropsMap {
|
|
38
|
+
Plane: PlaneProps;
|
|
39
|
+
Box: BoxProps;
|
|
40
|
+
Particle: ParticleProps;
|
|
41
|
+
Cylinder: CylinderProps;
|
|
42
|
+
Sphere: SphereProps;
|
|
43
|
+
Trimesh: TrimeshProps;
|
|
44
|
+
Heightfield: HeightfieldProps;
|
|
45
|
+
ConvexPolyhedron: ConvexPolyhedronProps;
|
|
46
|
+
Compound: CompoundBodyProps;
|
|
47
|
+
}
|
|
48
|
+
export type NgtcGetByIndex<T extends BodyProps> = (index: number) => T;
|
|
49
|
+
export type NgtcArgFn<T extends BodyProps> = (args: NonNullable<T['args']>) => typeof args;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { BodyProps, BoxProps, CannonWorkerAPI, CompoundBodyProps, ConvexPolyhedronArgs, CylinderArgs, HeightfieldArgs, ParticleProps, PlaneProps, PropValue, SphereArgs, SubscriptionName, SubscriptionTarget, Subscriptions, TrimeshArgs, Triplet } from '@pmndrs/cannon-worker-api';
|
|
2
|
+
import { NgtcCannonEvents, NgtcPhysicsApi } from 'angular-three-cannon';
|
|
3
|
+
import { Object3D } from 'three';
|
|
4
|
+
import { NgtcWorkerApi } from './types';
|
|
5
|
+
export declare function createSubscribe<T extends SubscriptionName>(body: Object3D, worker: CannonWorkerAPI, subscriptions: Subscriptions, type: T, index?: number, target?: SubscriptionTarget): (callback: (value: PropValue<T>) => void) => () => void;
|
|
6
|
+
export declare function prepare(object: Object3D, { position, rotation, userData }: BodyProps): void;
|
|
7
|
+
export declare function setupCollision(events: NgtcCannonEvents, { onCollide, onCollideBegin, onCollideEnd }: Partial<BodyProps>, uuid: string): void;
|
|
8
|
+
export declare function makeBodyApi(body: Object3D, worker: CannonWorkerAPI, { subscriptions, scaleOverrides }: Pick<NgtcPhysicsApi, 'subscriptions' | 'scaleOverrides'>): {
|
|
9
|
+
at: (index: number) => NgtcWorkerApi;
|
|
10
|
+
allowSleep: import("./types").NgtcAtomicApi<"allowSleep">;
|
|
11
|
+
angularDamping: import("./types").NgtcAtomicApi<"angularDamping">;
|
|
12
|
+
collisionFilterGroup: import("./types").NgtcAtomicApi<"collisionFilterGroup">;
|
|
13
|
+
collisionFilterMask: import("./types").NgtcAtomicApi<"collisionFilterMask">;
|
|
14
|
+
collisionResponse: import("./types").NgtcAtomicApi<"collisionResponse">;
|
|
15
|
+
fixedRotation: import("./types").NgtcAtomicApi<"fixedRotation">;
|
|
16
|
+
isTrigger: import("./types").NgtcAtomicApi<"isTrigger">;
|
|
17
|
+
linearDamping: import("./types").NgtcAtomicApi<"linearDamping">;
|
|
18
|
+
mass: import("./types").NgtcAtomicApi<"mass">;
|
|
19
|
+
material: import("./types").NgtcAtomicApi<"material">;
|
|
20
|
+
sleepSpeedLimit: import("./types").NgtcAtomicApi<"sleepSpeedLimit">;
|
|
21
|
+
sleepTimeLimit: import("./types").NgtcAtomicApi<"sleepTimeLimit">;
|
|
22
|
+
userData: import("./types").NgtcAtomicApi<"userData">;
|
|
23
|
+
angularFactor: import("./types").NgtcVectorApi;
|
|
24
|
+
angularVelocity: import("./types").NgtcVectorApi;
|
|
25
|
+
linearFactor: import("./types").NgtcVectorApi;
|
|
26
|
+
position: import("./types").NgtcVectorApi;
|
|
27
|
+
velocity: import("./types").NgtcVectorApi;
|
|
28
|
+
applyForce: (force: Triplet, worldPoint: Triplet) => void;
|
|
29
|
+
applyImpulse: (impulse: Triplet, worldPoint: Triplet) => void;
|
|
30
|
+
applyLocalForce: (force: Triplet, localPoint: Triplet) => void;
|
|
31
|
+
applyLocalImpulse: (impulse: Triplet, localPoint: Triplet) => void;
|
|
32
|
+
applyTorque: (torque: Triplet) => void;
|
|
33
|
+
quaternion: import("./types").NgtcQuaternionApi;
|
|
34
|
+
rotation: import("./types").NgtcVectorApi;
|
|
35
|
+
scaleOverride: (scale: Triplet) => void;
|
|
36
|
+
sleep: () => void;
|
|
37
|
+
wakeUp: () => void;
|
|
38
|
+
remove: () => void;
|
|
39
|
+
};
|
|
40
|
+
export declare const defaultTransformArgs: {
|
|
41
|
+
Plane: (_: PlaneProps["args"]) => never[];
|
|
42
|
+
Box: (args?: BoxProps["args"]) => Triplet;
|
|
43
|
+
Trimesh: (args: TrimeshArgs) => TrimeshArgs;
|
|
44
|
+
Cylinder: (_?: CylinderArgs) => never[];
|
|
45
|
+
Heightfield: (args: HeightfieldArgs) => HeightfieldArgs;
|
|
46
|
+
ConvexPolyhedron: ([vertices, faces, normals, axes, boundingSphereRadius]?: ConvexPolyhedronArgs) => (number | number[][] | undefined)[];
|
|
47
|
+
Particle: (_: ParticleProps["args"]) => never[];
|
|
48
|
+
Sphere: (args?: SphereArgs) => number[];
|
|
49
|
+
Compound: (args: CompoundBodyProps["args"]) => unknown[] | undefined;
|
|
50
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# `angular-three-cannon/constraint`
|
|
2
|
+
|
|
3
|
+
This module provides functions to create physics constraints that link physics bodies in the Cannon.js physics world. These functions simplify the process of adding constraints between your 3D objects.
|
|
4
|
+
|
|
5
|
+
### Available `inject*` Functions
|
|
6
|
+
|
|
7
|
+
| Function | Description | Arguments |
|
|
8
|
+
| :------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------- |
|
|
9
|
+
| `injectPointToPoint` | Creates a point-to-point constraint between two bodies. The constraint tries to keep the distance between the anchor points constant. | `objectA`, `objectB`, `getProps` |
|
|
10
|
+
| `injectConeTwist` | Creates a cone-twist constraint between two bodies. The constraint attempts to keep the bodies aligned along a common axis, allowing swing and twist motion. | `objectA`, `objectB`, `getProps` |
|
|
11
|
+
| `injectDistance` | Creates a distance constraint between two bodies. The constraint tries to keep the distance between the bodies' center of masses constant. | `objectA`, `objectB`, `getProps` |
|
|
12
|
+
| `injectLock` | Creates a lock constraint between two bodies. The constraint completely locks the motion of one body relative to another. | `objectA`, `objectB`, `getProps` |
|
|
13
|
+
| `injectHinge` | Creates a hinge constraint between two bodies. The constraint allows for rotation around a shared axis, like a door hinge. | `objectA`, `objectB`, `getProps` |
|
|
14
|
+
|
|
15
|
+
**All functions' `getProps` argument is a function that returns the properties of the constraint.**
|
|
16
|
+
|
|
17
|
+
### Simple Usage of `injectHinge()`
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { Component, viewChild, ElementRef } from '@angular/core';
|
|
21
|
+
import { injectHinge } from 'angular-three-cannon/constraint';
|
|
22
|
+
|
|
23
|
+
@Component({
|
|
24
|
+
template: `
|
|
25
|
+
<ngt-mesh #mesh1>
|
|
26
|
+
<ngt-box-geometry />
|
|
27
|
+
</ngt-mesh>
|
|
28
|
+
<ngt-mesh #mesh2>
|
|
29
|
+
<ngt-box-geometry />
|
|
30
|
+
</ngt-mesh>
|
|
31
|
+
`,
|
|
32
|
+
})
|
|
33
|
+
export class HingedBoxes {
|
|
34
|
+
mesh1 = viewChild.required<ElementRef<Mesh>>('mesh1');
|
|
35
|
+
mesh2 = viewChild.required<ElementRef<Mesh>>('mesh2');
|
|
36
|
+
|
|
37
|
+
constructor() {
|
|
38
|
+
// Create a hinge constraint between mesh1 and mesh2. Only works within <ngtc-physics>
|
|
39
|
+
injectHinge(this.mesh1, this.mesh2, () => ({
|
|
40
|
+
pivotA: [0, 0.5, 0], // hinge location on the first body
|
|
41
|
+
pivotB: [0, -0.5, 0], // hinge location on the second body
|
|
42
|
+
axisA: [0, 1, 0], // axis of rotation on the first body
|
|
43
|
+
axisB: [0, 1, 0], // axis of rotation on the second body
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib/constraint';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ElementRef, Injector, Signal } from '@angular/core';
|
|
2
|
+
import { ConeTwistConstraintOpts, ConstraintTypes, DistanceConstraintOpts, HingeConstraintOpts, LockConstraintOpts, PointToPointConstraintOpts } from '@pmndrs/cannon-worker-api';
|
|
3
|
+
import { Object3D } from 'three';
|
|
4
|
+
export interface NgtcConstraintApi {
|
|
5
|
+
disable: () => void;
|
|
6
|
+
enable: () => void;
|
|
7
|
+
remove: () => void;
|
|
8
|
+
}
|
|
9
|
+
export interface NgtcHingeConstraintApi extends NgtcConstraintApi {
|
|
10
|
+
disableMotor: () => void;
|
|
11
|
+
enableMotor: () => void;
|
|
12
|
+
setMotorMaxForce: (value: number) => void;
|
|
13
|
+
setMotorSpeed: (value: number) => void;
|
|
14
|
+
}
|
|
15
|
+
export type NgtcConstraintORHingeApi<T extends 'Hinge' | ConstraintTypes> = T extends ConstraintTypes ? NgtcConstraintApi : NgtcHingeConstraintApi;
|
|
16
|
+
export type NgtcConstraintOptionsMap = {
|
|
17
|
+
ConeTwist: ConeTwistConstraintOpts;
|
|
18
|
+
PointToPoint: PointToPointConstraintOpts;
|
|
19
|
+
Distance: DistanceConstraintOpts;
|
|
20
|
+
Lock: LockConstraintOpts;
|
|
21
|
+
Hinge: HingeConstraintOpts;
|
|
22
|
+
};
|
|
23
|
+
export type NgtcConstraintOptions<TConstraintType extends 'Hinge' | ConstraintTypes> = {
|
|
24
|
+
injector?: Injector;
|
|
25
|
+
disableOnStart?: boolean;
|
|
26
|
+
options?: NgtcConstraintOptionsMap[TConstraintType];
|
|
27
|
+
};
|
|
28
|
+
export declare const injectPointToPoint: <A extends Object3D = Object3D<import("three").Object3DEventMap>, B extends Object3D = Object3D<import("three").Object3DEventMap>>(bodyA: A | ElementRef<A> | Signal<A | ElementRef<A> | undefined>, bodyB: B | ElementRef<B> | Signal<B | ElementRef<B> | undefined>, options?: NgtcConstraintOptions<"PointToPoint"> | undefined) => Signal<NgtcConstraintApi | null>;
|
|
29
|
+
export declare const injectConeTwist: <A extends Object3D = Object3D<import("three").Object3DEventMap>, B extends Object3D = Object3D<import("three").Object3DEventMap>>(bodyA: A | ElementRef<A> | Signal<A | ElementRef<A> | undefined>, bodyB: B | ElementRef<B> | Signal<B | ElementRef<B> | undefined>, options?: NgtcConstraintOptions<"ConeTwist"> | undefined) => Signal<NgtcConstraintApi | null>;
|
|
30
|
+
export declare const injectDistance: <A extends Object3D = Object3D<import("three").Object3DEventMap>, B extends Object3D = Object3D<import("three").Object3DEventMap>>(bodyA: A | ElementRef<A> | Signal<A | ElementRef<A> | undefined>, bodyB: B | ElementRef<B> | Signal<B | ElementRef<B> | undefined>, options?: NgtcConstraintOptions<"Distance"> | undefined) => Signal<NgtcConstraintApi | null>;
|
|
31
|
+
export declare const injectLock: <A extends Object3D = Object3D<import("three").Object3DEventMap>, B extends Object3D = Object3D<import("three").Object3DEventMap>>(bodyA: A | ElementRef<A> | Signal<A | ElementRef<A> | undefined>, bodyB: B | ElementRef<B> | Signal<B | ElementRef<B> | undefined>, options?: NgtcConstraintOptions<"Lock"> | undefined) => Signal<NgtcConstraintApi | null>;
|
|
32
|
+
export declare const injectHinge: <A extends Object3D = Object3D<import("three").Object3DEventMap>, B extends Object3D = Object3D<import("three").Object3DEventMap>>(bodyA: A | ElementRef<A> | Signal<A | ElementRef<A> | undefined>, bodyB: B | ElementRef<B> | Signal<B | ElementRef<B> | undefined>, options?: NgtcConstraintOptions<"Hinge"> | undefined) => Signal<NgtcConstraintApi | null>;
|
package/debug/README.md
CHANGED
|
@@ -1,3 +1,49 @@
|
|
|
1
|
-
# angular-three-cannon/debug
|
|
1
|
+
# `angular-three-cannon/debug`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This module provides the `NgtcDebug` directive, which allows you to visualize the physics bodies within your Angular Three Cannon simulations.
|
|
4
|
+
|
|
5
|
+
| Package | Description |
|
|
6
|
+
| -------------------- | ---------------------------------------------- |
|
|
7
|
+
| `cannon-es-debugger` | A debug renderer for Cannon.js physics engine. |
|
|
8
|
+
|
|
9
|
+
This entry point requires the `cannon-es-debugger` package to be installed.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install cannon-es-debugger
|
|
13
|
+
# yarn add cannon-es-debugger
|
|
14
|
+
# pnpm add cannon-es-debugger
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## NgtcDebugApi
|
|
18
|
+
|
|
19
|
+
The `NgtcDebugApi` interface provides methods to interact with the debug renderer:
|
|
20
|
+
|
|
21
|
+
- `add(uuid: string, props: BodyProps, type: BodyShapeType)`: Adds a physics body to the debug renderer.
|
|
22
|
+
- `remove(uuid: string)`: Removes a physics body from the debug renderer.
|
|
23
|
+
|
|
24
|
+
### `injectNgtcDebugApi`
|
|
25
|
+
|
|
26
|
+
The `injectNgtcDebugApi` function is used to inject the `NgtcDebugApi` into your components, enabling you to control the debug visualization.
|
|
27
|
+
|
|
28
|
+
## NgtcDebug
|
|
29
|
+
|
|
30
|
+
The `NgtcDebug` directive is applied to the `ngtc-physics` component to enable physics debugging. It has the following inputs:
|
|
31
|
+
|
|
32
|
+
- `debug`: An object containing the following properties:
|
|
33
|
+
|
|
34
|
+
- `enabled`: (boolean) Whether the debug visualization is enabled (default: true).
|
|
35
|
+
- `color`: (string) The color of the debug visualization (default: 'black').
|
|
36
|
+
- `impl`: (typeof CannonDebugger) The implementation of the CannonDebugger to use (default: CannonDebugger).
|
|
37
|
+
- `scale`: (number) The scale of the debug visualization (default: 1).
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<ngtc-physics debug></ngtc-physics>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
You can customize the debug visualization by providing input values within the `debug` object:
|
|
46
|
+
|
|
47
|
+
```html
|
|
48
|
+
<ngtc-physics [debug]="{enabled: true, color: 'red', scale: 0.5}"></ngtc-physics>
|
|
49
|
+
```
|
package/debug/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './debug';
|
|
1
|
+
export * from './lib/debug';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BodyProps, BodyShapeType } from '@pmndrs/cannon-worker-api';
|
|
2
|
+
import CannonDebugger from 'cannon-es-debugger';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export interface NgtcDebugInputs {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
color: string;
|
|
7
|
+
impl: typeof CannonDebugger;
|
|
8
|
+
scale: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class NgtcDebug {
|
|
11
|
+
private store;
|
|
12
|
+
private physics;
|
|
13
|
+
debug: import("@angular/core").InputSignalWithTransform<NgtcDebugInputs, "" | Partial<NgtcDebugInputs>>;
|
|
14
|
+
private defaultScene;
|
|
15
|
+
private scene;
|
|
16
|
+
private bodies;
|
|
17
|
+
private bodyMap;
|
|
18
|
+
private cannonDebugger;
|
|
19
|
+
api: {};
|
|
20
|
+
constructor();
|
|
21
|
+
add(uuid: string, props: BodyProps, type: BodyShapeType): void;
|
|
22
|
+
remove(uuid: string): void;
|
|
23
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgtcDebug, never>;
|
|
24
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NgtcDebug, "ngtc-physics[debug]", never, { "debug": { "alias": "debug"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './index';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci10aHJlZS1jYW5ub24tYm9keS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvY2Fubm9uL2JvZHkvc3JjL2FuZ3VsYXItdGhyZWUtY2Fubm9uLWJvZHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLFNBQVMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9pbmRleCc7XG4iXX0=
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export * from './lib/body';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2Nhbm5vbi9ib2R5L3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vbGliL2JvZHknO1xuZXhwb3J0IHR5cGUgKiBmcm9tICcuL2xpYi90eXBlcyc7XG4iXX0=
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { computed, effect, inject, isSignal, signal, untracked, } from '@angular/core';
|
|
2
|
+
import { resolveRef } from 'angular-three';
|
|
3
|
+
import { NgtcPhysics } from 'angular-three-cannon';
|
|
4
|
+
import { NgtcDebug } from 'angular-three-cannon/debug';
|
|
5
|
+
import { assertInjector } from 'ngxtension/assert-injector';
|
|
6
|
+
import { DynamicDrawUsage, InstancedMesh, Object3D } from 'three';
|
|
7
|
+
import { defaultTransformArgs, makeBodyApi, prepare, setupCollision } from './utils';
|
|
8
|
+
function createInjectBody(type) {
|
|
9
|
+
return (getPropFn, ref, options) => injectBody(type, getPropFn, ref, options);
|
|
10
|
+
}
|
|
11
|
+
function injectBody(type, getPropFn, ref, { transformArgs, injector } = {}) {
|
|
12
|
+
return assertInjector(injectBody, injector, () => {
|
|
13
|
+
const physics = inject(NgtcPhysics, { optional: true });
|
|
14
|
+
if (!physics) {
|
|
15
|
+
throw new Error(`[NGT Cannon] injectBody was called outside of <ngtc-physics>`);
|
|
16
|
+
}
|
|
17
|
+
const debug = inject(NgtcDebug, { optional: true });
|
|
18
|
+
const transform = transformArgs ?? defaultTransformArgs[type];
|
|
19
|
+
const bodyRef = isSignal(ref) ? ref : signal(ref);
|
|
20
|
+
const body = computed(() => resolveRef(bodyRef()));
|
|
21
|
+
const api = computed(() => {
|
|
22
|
+
const _body = body();
|
|
23
|
+
if (!_body)
|
|
24
|
+
return null;
|
|
25
|
+
const { worker, ...rest } = physics.api;
|
|
26
|
+
if (!worker())
|
|
27
|
+
return null;
|
|
28
|
+
return makeBodyApi(_body, worker(), rest);
|
|
29
|
+
});
|
|
30
|
+
effect((onCleanup) => {
|
|
31
|
+
const currentWorker = physics.api.worker();
|
|
32
|
+
if (!currentWorker)
|
|
33
|
+
return;
|
|
34
|
+
const object = body();
|
|
35
|
+
if (!isSignal(ref) && !object) {
|
|
36
|
+
untracked(() => {
|
|
37
|
+
bodyRef.set(resolveRef(ref));
|
|
38
|
+
});
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!object)
|
|
42
|
+
return;
|
|
43
|
+
const [uuid, props] = (() => {
|
|
44
|
+
let uuids = [];
|
|
45
|
+
let temp;
|
|
46
|
+
if (object instanceof InstancedMesh) {
|
|
47
|
+
object.instanceMatrix.setUsage(DynamicDrawUsage);
|
|
48
|
+
uuids = new Array(object.count).fill(0).map((_, i) => `${object.uuid}/${i}`);
|
|
49
|
+
temp = new Object3D();
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
uuids = [object.uuid];
|
|
53
|
+
}
|
|
54
|
+
return [
|
|
55
|
+
uuids,
|
|
56
|
+
uuids.map((id, index) => {
|
|
57
|
+
const props = getPropFn(index);
|
|
58
|
+
if (temp) {
|
|
59
|
+
prepare(temp, props);
|
|
60
|
+
object.setMatrixAt(index, temp.matrix);
|
|
61
|
+
object.instanceMatrix.needsUpdate = true;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
prepare(object, props);
|
|
65
|
+
}
|
|
66
|
+
physics.api.refs[id] = object;
|
|
67
|
+
debug?.add(id, props, type);
|
|
68
|
+
setupCollision(physics.api.events, props, id);
|
|
69
|
+
// @ts-expect-error - if args is undefined, there's default
|
|
70
|
+
return { ...props, args: transform(props.args) };
|
|
71
|
+
}),
|
|
72
|
+
];
|
|
73
|
+
})();
|
|
74
|
+
// Register on mount, unregister on unmount
|
|
75
|
+
currentWorker.addBodies({
|
|
76
|
+
props: props.map(({ onCollide, onCollideBegin, onCollideEnd, ...serializableProps }) => {
|
|
77
|
+
return {
|
|
78
|
+
onCollide: Boolean(onCollide),
|
|
79
|
+
onCollideBegin: Boolean(onCollideBegin),
|
|
80
|
+
onCollideEnd: Boolean(onCollideEnd),
|
|
81
|
+
...serializableProps,
|
|
82
|
+
};
|
|
83
|
+
}),
|
|
84
|
+
type,
|
|
85
|
+
uuid,
|
|
86
|
+
});
|
|
87
|
+
onCleanup(() => {
|
|
88
|
+
uuid.forEach((id) => {
|
|
89
|
+
delete physics.api.refs[id];
|
|
90
|
+
debug?.remove(id);
|
|
91
|
+
delete physics.api.events[id];
|
|
92
|
+
});
|
|
93
|
+
currentWorker.removeBodies({ uuid });
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
return api;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export const injectBox = createInjectBody('Box');
|
|
100
|
+
export const injectConvexPolyhedron = createInjectBody('ConvexPolyhedron');
|
|
101
|
+
export const injectCylinder = createInjectBody('Cylinder');
|
|
102
|
+
export const injectHeightfield = createInjectBody('Heightfield');
|
|
103
|
+
export const injectParticle = createInjectBody('Particle');
|
|
104
|
+
export const injectPlane = createInjectBody('Plane');
|
|
105
|
+
export const injectSphere = createInjectBody('Sphere');
|
|
106
|
+
export const injectTrimesh = createInjectBody('Trimesh');
|
|
107
|
+
export const injectCompound = createInjectBody('Compound');
|
|
108
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY2Fubm9uL2JvZHkvc3JjL2xpYi9ib2R5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFLTixRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsR0FDVCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzVELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBRWxFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQU9yRixTQUFTLGdCQUFnQixDQUErQixJQUFZO0lBQ25FLE9BQU8sQ0FDTixTQUFtRCxFQUNuRCxHQUFzRixFQUN0RixPQUFpQyxFQUNoQyxFQUFFLENBQUMsVUFBVSxDQUFrQixJQUFJLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNqRSxDQUFDO0FBRUQsU0FBUyxVQUFVLENBQ2xCLElBQVksRUFDWixTQUFtRCxFQUNuRCxHQUFzRixFQUN0RixFQUFFLGFBQWEsRUFBRSxRQUFRLEtBQThCLEVBQUU7SUFFekQsT0FBTyxjQUFjLENBQUMsVUFBVSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7UUFDaEQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFdBQVcsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXhELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztRQUNqRixDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFNBQVMsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXBELE1BQU0sU0FBUyxHQUFHLGFBQWEsSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5RCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRW5ELE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDekIsTUFBTSxLQUFLLEdBQUcsSUFBSSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFDeEIsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDeEMsSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFBRSxPQUFPLElBQUksQ0FBQztZQUMzQixPQUFPLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtZQUNwQixNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzNDLElBQUksQ0FBQyxhQUFhO2dCQUFFLE9BQU87WUFFM0IsTUFBTSxNQUFNLEdBQUcsSUFBSSxFQUFFLENBQUM7WUFFdEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUMvQixTQUFTLENBQUMsR0FBRyxFQUFFO29CQUNiLE9BQStDLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN2RSxDQUFDLENBQUMsQ0FBQztnQkFDSCxPQUFPO1lBQ1IsQ0FBQztZQUVELElBQUksQ0FBQyxNQUFNO2dCQUFFLE9BQU87WUFFcEIsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQkFDM0IsSUFBSSxLQUFLLEdBQWEsRUFBRSxDQUFDO2dCQUN6QixJQUFJLElBQWMsQ0FBQztnQkFDbkIsSUFBSSxNQUFNLFlBQVksYUFBYSxFQUFFLENBQUM7b0JBQ3JDLE1BQU0sQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUM7b0JBQ2pELEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUM3RSxJQUFJLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDdkIsQ0FBQztxQkFBTSxDQUFDO29CQUNQLEtBQUssR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDdkIsQ0FBQztnQkFDRCxPQUFPO29CQUNOLEtBQUs7b0JBQ0wsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsRUFBRTt3QkFDdkIsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO3dCQUMvQixJQUFJLElBQUksRUFBRSxDQUFDOzRCQUNWLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7NEJBQ3BCLE1BQW1DLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7NEJBQ3BFLE1BQW1DLENBQUMsY0FBYyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7d0JBQ3hFLENBQUM7NkJBQU0sQ0FBQzs0QkFDUCxPQUFPLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO3dCQUN4QixDQUFDO3dCQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQzt3QkFDOUIsS0FBSyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO3dCQUM1QixjQUFjLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO3dCQUM5QywyREFBMkQ7d0JBQzNELE9BQU8sRUFBRSxHQUFHLEtBQUssRUFBRSxJQUFJLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNsRCxDQUFDLENBQUM7aUJBQ0YsQ0FBQztZQUNILENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDTCwyQ0FBMkM7WUFDM0MsYUFBYSxDQUFDLFNBQVMsQ0FBQztnQkFDdkIsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLEdBQUcsaUJBQWlCLEVBQUUsRUFBRSxFQUFFO29CQUN0RixPQUFPO3dCQUNOLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxDQUFDO3dCQUM3QixjQUFjLEVBQUUsT0FBTyxDQUFDLGNBQWMsQ0FBQzt3QkFDdkMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxZQUFZLENBQUM7d0JBQ25DLEdBQUcsaUJBQWlCO3FCQUNwQixDQUFDO2dCQUNILENBQUMsQ0FBQztnQkFDRixJQUFJO2dCQUNKLElBQUk7YUFDSixDQUFDLENBQUM7WUFFSCxTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtvQkFDbkIsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFDNUIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFDbEIsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDL0IsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsYUFBYSxDQUFDLFlBQVksQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sR0FBRyxDQUFDO0lBQ1osQ0FBQyxDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2pELE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLGdCQUFnQixDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFDM0UsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzNELE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ2pFLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUMzRCxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDckQsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3ZELE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUN6RCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuXHRFbGVtZW50UmVmLFxuXHRJbmplY3Rvcixcblx0U2lnbmFsLFxuXHRXcml0YWJsZVNpZ25hbCxcblx0Y29tcHV0ZWQsXG5cdGVmZmVjdCxcblx0aW5qZWN0LFxuXHRpc1NpZ25hbCxcblx0c2lnbmFsLFxuXHR1bnRyYWNrZWQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQm9keVNoYXBlVHlwZSB9IGZyb20gJ0BwbW5kcnMvY2Fubm9uLXdvcmtlci1hcGknO1xuaW1wb3J0IHsgcmVzb2x2ZVJlZiB9IGZyb20gJ2FuZ3VsYXItdGhyZWUnO1xuaW1wb3J0IHsgTmd0Y1BoeXNpY3MgfSBmcm9tICdhbmd1bGFyLXRocmVlLWNhbm5vbic7XG5pbXBvcnQgeyBOZ3RjRGVidWcgfSBmcm9tICdhbmd1bGFyLXRocmVlLWNhbm5vbi9kZWJ1Zyc7XG5pbXBvcnQgeyBhc3NlcnRJbmplY3RvciB9IGZyb20gJ25neHRlbnNpb24vYXNzZXJ0LWluamVjdG9yJztcbmltcG9ydCB7IER5bmFtaWNEcmF3VXNhZ2UsIEluc3RhbmNlZE1lc2gsIE9iamVjdDNEIH0gZnJvbSAndGhyZWUnO1xuaW1wb3J0IHsgTmd0Y0FyZ0ZuLCBOZ3RjQm9keVByb3BzTWFwLCBOZ3RjQm9keVB1YmxpY0FwaSwgTmd0Y0dldEJ5SW5kZXggfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGRlZmF1bHRUcmFuc2Zvcm1BcmdzLCBtYWtlQm9keUFwaSwgcHJlcGFyZSwgc2V0dXBDb2xsaXNpb24gfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBOZ3RjQm9keU9wdGlvbnM8VFNoYXBlIGV4dGVuZHMgQm9keVNoYXBlVHlwZT4ge1xuXHR0cmFuc2Zvcm1BcmdzPzogTmd0Y0FyZ0ZuPE5ndGNCb2R5UHJvcHNNYXBbVFNoYXBlXT47XG5cdGluamVjdG9yPzogSW5qZWN0b3I7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUluamVjdEJvZHk8VFNoYXBlIGV4dGVuZHMgQm9keVNoYXBlVHlwZT4odHlwZTogVFNoYXBlKSB7XG5cdHJldHVybiA8VE9iamVjdCBleHRlbmRzIE9iamVjdDNEPihcblx0XHRnZXRQcm9wRm46IE5ndGNHZXRCeUluZGV4PE5ndGNCb2R5UHJvcHNNYXBbVFNoYXBlXT4sXG5cdFx0cmVmOiBFbGVtZW50UmVmPFRPYmplY3Q+IHwgVE9iamVjdCB8IFNpZ25hbDxFbGVtZW50UmVmPFRPYmplY3Q+IHwgVE9iamVjdCB8IHVuZGVmaW5lZD4sXG5cdFx0b3B0aW9ucz86IE5ndGNCb2R5T3B0aW9uczxUU2hhcGU+LFxuXHQpID0+IGluamVjdEJvZHk8VFNoYXBlLCBUT2JqZWN0Pih0eXBlLCBnZXRQcm9wRm4sIHJlZiwgb3B0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGluamVjdEJvZHk8VFNoYXBlIGV4dGVuZHMgQm9keVNoYXBlVHlwZSwgVE9iamVjdCBleHRlbmRzIE9iamVjdDNEPihcblx0dHlwZTogVFNoYXBlLFxuXHRnZXRQcm9wRm46IE5ndGNHZXRCeUluZGV4PE5ndGNCb2R5UHJvcHNNYXBbVFNoYXBlXT4sXG5cdHJlZjogRWxlbWVudFJlZjxUT2JqZWN0PiB8IFRPYmplY3QgfCBTaWduYWw8RWxlbWVudFJlZjxUT2JqZWN0PiB8IFRPYmplY3QgfCB1bmRlZmluZWQ+LFxuXHR7IHRyYW5zZm9ybUFyZ3MsIGluamVjdG9yIH06IE5ndGNCb2R5T3B0aW9uczxUU2hhcGU+ID0ge30sXG4pOiBTaWduYWw8Tmd0Y0JvZHlQdWJsaWNBcGkgfCBudWxsPiB7XG5cdHJldHVybiBhc3NlcnRJbmplY3RvcihpbmplY3RCb2R5LCBpbmplY3RvciwgKCkgPT4ge1xuXHRcdGNvbnN0IHBoeXNpY3MgPSBpbmplY3QoTmd0Y1BoeXNpY3MsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cblx0XHRpZiAoIXBoeXNpY3MpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihgW05HVCBDYW5ub25dIGluamVjdEJvZHkgd2FzIGNhbGxlZCBvdXRzaWRlIG9mIDxuZ3RjLXBoeXNpY3M+YCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZGVidWcgPSBpbmplY3QoTmd0Y0RlYnVnLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG5cdFx0Y29uc3QgdHJhbnNmb3JtID0gdHJhbnNmb3JtQXJncyA/PyBkZWZhdWx0VHJhbnNmb3JtQXJnc1t0eXBlXTtcblx0XHRjb25zdCBib2R5UmVmID0gaXNTaWduYWwocmVmKSA/IHJlZiA6IHNpZ25hbChyZWYpO1xuXHRcdGNvbnN0IGJvZHkgPSBjb21wdXRlZCgoKSA9PiByZXNvbHZlUmVmKGJvZHlSZWYoKSkpO1xuXG5cdFx0Y29uc3QgYXBpID0gY29tcHV0ZWQoKCkgPT4ge1xuXHRcdFx0Y29uc3QgX2JvZHkgPSBib2R5KCk7XG5cdFx0XHRpZiAoIV9ib2R5KSByZXR1cm4gbnVsbDtcblx0XHRcdGNvbnN0IHsgd29ya2VyLCAuLi5yZXN0IH0gPSBwaHlzaWNzLmFwaTtcblx0XHRcdGlmICghd29ya2VyKCkpIHJldHVybiBudWxsO1xuXHRcdFx0cmV0dXJuIG1ha2VCb2R5QXBpKF9ib2R5LCB3b3JrZXIoKSwgcmVzdCk7XG5cdFx0fSk7XG5cblx0XHRlZmZlY3QoKG9uQ2xlYW51cCkgPT4ge1xuXHRcdFx0Y29uc3QgY3VycmVudFdvcmtlciA9IHBoeXNpY3MuYXBpLndvcmtlcigpO1xuXHRcdFx0aWYgKCFjdXJyZW50V29ya2VyKSByZXR1cm47XG5cblx0XHRcdGNvbnN0IG9iamVjdCA9IGJvZHkoKTtcblxuXHRcdFx0aWYgKCFpc1NpZ25hbChyZWYpICYmICFvYmplY3QpIHtcblx0XHRcdFx0dW50cmFja2VkKCgpID0+IHtcblx0XHRcdFx0XHQoYm9keVJlZiBhcyBXcml0YWJsZVNpZ25hbDxUT2JqZWN0IHwgdW5kZWZpbmVkPikuc2V0KHJlc29sdmVSZWYocmVmKSk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICghb2JqZWN0KSByZXR1cm47XG5cblx0XHRcdGNvbnN0IFt1dWlkLCBwcm9wc10gPSAoKCkgPT4ge1xuXHRcdFx0XHRsZXQgdXVpZHM6IHN0cmluZ1tdID0gW107XG5cdFx0XHRcdGxldCB0ZW1wOiBPYmplY3QzRDtcblx0XHRcdFx0aWYgKG9iamVjdCBpbnN0YW5jZW9mIEluc3RhbmNlZE1lc2gpIHtcblx0XHRcdFx0XHRvYmplY3QuaW5zdGFuY2VNYXRyaXguc2V0VXNhZ2UoRHluYW1pY0RyYXdVc2FnZSk7XG5cdFx0XHRcdFx0dXVpZHMgPSBuZXcgQXJyYXkob2JqZWN0LmNvdW50KS5maWxsKDApLm1hcCgoXywgaSkgPT4gYCR7b2JqZWN0LnV1aWR9LyR7aX1gKTtcblx0XHRcdFx0XHR0ZW1wID0gbmV3IE9iamVjdDNEKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dXVpZHMgPSBbb2JqZWN0LnV1aWRdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBbXG5cdFx0XHRcdFx0dXVpZHMsXG5cdFx0XHRcdFx0dXVpZHMubWFwKChpZCwgaW5kZXgpID0+IHtcblx0XHRcdFx0XHRcdGNvbnN0IHByb3BzID0gZ2V0UHJvcEZuKGluZGV4KTtcblx0XHRcdFx0XHRcdGlmICh0ZW1wKSB7XG5cdFx0XHRcdFx0XHRcdHByZXBhcmUodGVtcCwgcHJvcHMpO1xuXHRcdFx0XHRcdFx0XHQob2JqZWN0IGFzIHVua25vd24gYXMgSW5zdGFuY2VkTWVzaCkuc2V0TWF0cml4QXQoaW5kZXgsIHRlbXAubWF0cml4KTtcblx0XHRcdFx0XHRcdFx0KG9iamVjdCBhcyB1bmtub3duIGFzIEluc3RhbmNlZE1lc2gpLmluc3RhbmNlTWF0cml4Lm5lZWRzVXBkYXRlID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHByZXBhcmUob2JqZWN0LCBwcm9wcyk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRwaHlzaWNzLmFwaS5yZWZzW2lkXSA9IG9iamVjdDtcblx0XHRcdFx0XHRcdGRlYnVnPy5hZGQoaWQsIHByb3BzLCB0eXBlKTtcblx0XHRcdFx0XHRcdHNldHVwQ29sbGlzaW9uKHBoeXNpY3MuYXBpLmV2ZW50cywgcHJvcHMsIGlkKTtcblx0XHRcdFx0XHRcdC8vIEB0cy1leHBlY3QtZXJyb3IgLSBpZiBhcmdzIGlzIHVuZGVmaW5lZCwgdGhlcmUncyBkZWZhdWx0XG5cdFx0XHRcdFx0XHRyZXR1cm4geyAuLi5wcm9wcywgYXJnczogdHJhbnNmb3JtKHByb3BzLmFyZ3MpIH07XG5cdFx0XHRcdFx0fSksXG5cdFx0XHRcdF07XG5cdFx0XHR9KSgpO1xuXHRcdFx0Ly8gUmVnaXN0ZXIgb24gbW91bnQsIHVucmVnaXN0ZXIgb24gdW5tb3VudFxuXHRcdFx0Y3VycmVudFdvcmtlci5hZGRCb2RpZXMoe1xuXHRcdFx0XHRwcm9wczogcHJvcHMubWFwKCh7IG9uQ29sbGlkZSwgb25Db2xsaWRlQmVnaW4sIG9uQ29sbGlkZUVuZCwgLi4uc2VyaWFsaXphYmxlUHJvcHMgfSkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRvbkNvbGxpZGU6IEJvb2xlYW4ob25Db2xsaWRlKSxcblx0XHRcdFx0XHRcdG9uQ29sbGlkZUJlZ2luOiBCb29sZWFuKG9uQ29sbGlkZUJlZ2luKSxcblx0XHRcdFx0XHRcdG9uQ29sbGlkZUVuZDogQm9vbGVhbihvbkNvbGxpZGVFbmQpLFxuXHRcdFx0XHRcdFx0Li4uc2VyaWFsaXphYmxlUHJvcHMsXG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fSksXG5cdFx0XHRcdHR5cGUsXG5cdFx0XHRcdHV1aWQsXG5cdFx0XHR9KTtcblxuXHRcdFx0b25DbGVhbnVwKCgpID0+IHtcblx0XHRcdFx0dXVpZC5mb3JFYWNoKChpZCkgPT4ge1xuXHRcdFx0XHRcdGRlbGV0ZSBwaHlzaWNzLmFwaS5yZWZzW2lkXTtcblx0XHRcdFx0XHRkZWJ1Zz8ucmVtb3ZlKGlkKTtcblx0XHRcdFx0XHRkZWxldGUgcGh5c2ljcy5hcGkuZXZlbnRzW2lkXTtcblx0XHRcdFx0fSk7XG5cdFx0XHRcdGN1cnJlbnRXb3JrZXIucmVtb3ZlQm9kaWVzKHsgdXVpZCB9KTtcblx0XHRcdH0pO1xuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIGFwaTtcblx0fSk7XG59XG5cbmV4cG9ydCBjb25zdCBpbmplY3RCb3ggPSBjcmVhdGVJbmplY3RCb2R5KCdCb3gnKTtcbmV4cG9ydCBjb25zdCBpbmplY3RDb252ZXhQb2x5aGVkcm9uID0gY3JlYXRlSW5qZWN0Qm9keSgnQ29udmV4UG9seWhlZHJvbicpO1xuZXhwb3J0IGNvbnN0IGluamVjdEN5bGluZGVyID0gY3JlYXRlSW5qZWN0Qm9keSgnQ3lsaW5kZXInKTtcbmV4cG9ydCBjb25zdCBpbmplY3RIZWlnaHRmaWVsZCA9IGNyZWF0ZUluamVjdEJvZHkoJ0hlaWdodGZpZWxkJyk7XG5leHBvcnQgY29uc3QgaW5qZWN0UGFydGljbGUgPSBjcmVhdGVJbmplY3RCb2R5KCdQYXJ0aWNsZScpO1xuZXhwb3J0IGNvbnN0IGluamVjdFBsYW5lID0gY3JlYXRlSW5qZWN0Qm9keSgnUGxhbmUnKTtcbmV4cG9ydCBjb25zdCBpbmplY3RTcGhlcmUgPSBjcmVhdGVJbmplY3RCb2R5KCdTcGhlcmUnKTtcbmV4cG9ydCBjb25zdCBpbmplY3RUcmltZXNoID0gY3JlYXRlSW5qZWN0Qm9keSgnVHJpbWVzaCcpO1xuZXhwb3J0IGNvbnN0IGluamVjdENvbXBvdW5kID0gY3JlYXRlSW5qZWN0Qm9keSgnQ29tcG91bmQnKTtcbiJdfQ==
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2Nhbm5vbi9ib2R5L3NyYy9saWIvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdEF0b21pY05hbWUsXG5cdEF0b21pY1Byb3BzLFxuXHRCb2R5UHJvcHMsXG5cdEJveFByb3BzLFxuXHRDb21wb3VuZEJvZHlQcm9wcyxcblx0Q29udmV4UG9seWhlZHJvblByb3BzLFxuXHRDeWxpbmRlclByb3BzLFxuXHRIZWlnaHRmaWVsZFByb3BzLFxuXHRQYXJ0aWNsZVByb3BzLFxuXHRQbGFuZVByb3BzLFxuXHRRdWFkLFxuXHRTcGhlcmVQcm9wcyxcblx0VHJpbWVzaFByb3BzLFxuXHRUcmlwbGV0LFxuXHRWZWN0b3JOYW1lLFxufSBmcm9tICdAcG1uZHJzL2Nhbm5vbi13b3JrZXItYXBpJztcbmltcG9ydCB7IEV1bGVyLCBRdWF0ZXJuaW9uLCBWZWN0b3IzIH0gZnJvbSAndGhyZWUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5ndGNBdG9taWNBcGk8SyBleHRlbmRzIEF0b21pY05hbWU+IHtcblx0c2V0OiAodmFsdWU6IEF0b21pY1Byb3BzW0tdKSA9PiB2b2lkO1xuXHRzdWJzY3JpYmU6IChjYWxsYmFjazogKHZhbHVlOiBBdG9taWNQcm9wc1tLXSkgPT4gdm9pZCkgPT4gKCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZ3RjUXVhdGVybmlvbkFwaSB7XG5cdGNvcHk6ICh7IHcsIHgsIHksIHogfTogUXVhdGVybmlvbikgPT4gdm9pZDtcblx0c2V0OiAoeDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlciwgdzogbnVtYmVyKSA9PiB2b2lkO1xuXHRzdWJzY3JpYmU6IChjYWxsYmFjazogKHZhbHVlOiBRdWFkKSA9PiB2b2lkKSA9PiAoKSA9PiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5ndGNWZWN0b3JBcGkge1xuXHRjb3B5OiAoeyB4LCB5LCB6IH06IFZlY3RvcjMgfCBFdWxlcikgPT4gdm9pZDtcblx0c2V0OiAoeDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlcikgPT4gdm9pZDtcblx0c3Vic2NyaWJlOiAoY2FsbGJhY2s6ICh2YWx1ZTogVHJpcGxldCkgPT4gdm9pZCkgPT4gKCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IHR5cGUgTmd0Y1dvcmtlckFwaSA9IHtcblx0W0sgaW4gQXRvbWljTmFtZV06IE5ndGNBdG9taWNBcGk8Sz47XG59ICYge1xuXHRbSyBpbiBWZWN0b3JOYW1lXTogTmd0Y1ZlY3RvckFwaTtcbn0gJiB7XG5cdGFwcGx5Rm9yY2U6IChmb3JjZTogVHJpcGxldCwgd29ybGRQb2ludDogVHJpcGxldCkgPT4gdm9pZDtcblx0YXBwbHlJbXB1bHNlOiAoaW1wdWxzZTogVHJpcGxldCwgd29ybGRQb2ludDogVHJpcGxldCkgPT4gdm9pZDtcblx0YXBwbHlMb2NhbEZvcmNlOiAoZm9yY2U6IFRyaXBsZXQsIGxvY2FsUG9pbnQ6IFRyaXBsZXQpID0+IHZvaWQ7XG5cdGFwcGx5TG9jYWxJbXB1bHNlOiAoaW1wdWxzZTogVHJpcGxldCwgbG9jYWxQb2ludDogVHJpcGxldCkgPT4gdm9pZDtcblx0YXBwbHlUb3JxdWU6ICh0b3JxdWU6IFRyaXBsZXQpID0+IHZvaWQ7XG5cdHF1YXRlcm5pb246IE5ndGNRdWF0ZXJuaW9uQXBpO1xuXHRyb3RhdGlvbjogTmd0Y1ZlY3RvckFwaTtcblx0c2NhbGVPdmVycmlkZTogKHNjYWxlOiBUcmlwbGV0KSA9PiB2b2lkO1xuXHRzbGVlcDogKCkgPT4gdm9pZDtcblx0d2FrZVVwOiAoKSA9PiB2b2lkO1xuXHRyZW1vdmU6ICgpID0+IHZvaWQ7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIE5ndGNCb2R5UHVibGljQXBpIGV4dGVuZHMgTmd0Y1dvcmtlckFwaSB7XG5cdGF0OiAoaW5kZXg6IG51bWJlcikgPT4gTmd0Y1dvcmtlckFwaTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZ3RjQm9keVByb3BzTWFwIHtcblx0UGxhbmU6IFBsYW5lUHJvcHM7XG5cdEJveDogQm94UHJvcHM7XG5cdFBhcnRpY2xlOiBQYXJ0aWNsZVByb3BzO1xuXHRDeWxpbmRlcjogQ3lsaW5kZXJQcm9wcztcblx0U3BoZXJlOiBTcGhlcmVQcm9wcztcblx0VHJpbWVzaDogVHJpbWVzaFByb3BzO1xuXHRIZWlnaHRmaWVsZDogSGVpZ2h0ZmllbGRQcm9wcztcblx0Q29udmV4UG9seWhlZHJvbjogQ29udmV4UG9seWhlZHJvblByb3BzO1xuXHRDb21wb3VuZDogQ29tcG91bmRCb2R5UHJvcHM7XG59XG5cbmV4cG9ydCB0eXBlIE5ndGNHZXRCeUluZGV4PFQgZXh0ZW5kcyBCb2R5UHJvcHM+ID0gKGluZGV4OiBudW1iZXIpID0+IFQ7XG5leHBvcnQgdHlwZSBOZ3RjQXJnRm48VCBleHRlbmRzIEJvZHlQcm9wcz4gPSAoYXJnczogTm9uTnVsbGFibGU8VFsnYXJncyddPikgPT4gdHlwZW9mIGFyZ3M7XG4iXX0=
|